repo create: guard repoCreateOutput against a nil repo · Entire

repo create: guard repoCreateOutput against a nil repo

cce6f83→main·

stiak·1mo ago·2 files·+14 added/-0 removed

repoCreateOutput dereferenced its *Repo argument (via *r in the remote synthesis) without a nil check. The sole caller only passes a repo after a nil-error create, so this defends the contract rather than a live path — but a nil pointer would slip past json.Marshal (which encodes a nil pointer as "null" without error) and panic later on the dereference. Return an error up front instead.

Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

Sessions

fade5f8ccb64View transcript

?\ Fix .remote Field Stamping in Repo CreateClaude Code·Opus 4.8[1m]·1 step

Changes

2

2 unmodified lines

3
4
5
6
7
8
9
59 unmodified lines

69
70
71
72
73
74
75
76
77

2 unmodified lines

import (
    "context"
    "encoding/json"
    "errors"
    "fmt"
    "strings"

59 unmodified lines

// server-provided value always wins. The field is omitted when the clone
// coordinates aren't resolvable yet rather than emitted half-formed.
func repoCreateOutput(r *coreapi.Repo) (any, error) {
    if r == nil {
        return nil, errors.New("nil repo")
    }
    raw, err := json.Marshal(r)
    if err != nil {
        return nil, fmt.Errorf("encode repo: %w", err)

Mcmd/entire/cli/repo.go+4

127 unmodified lines

128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143

127 unmodified lines

}
}

func TestRepoCreateOutput_NilRepoErrors(t *testing.T) {
    t.Parallel()
    // Defends the contract rather than a real path (the caller only passes a
    // repo after a nil-error create): a nil pointer must return an error, not
    // panic on the later dereference.
    if _, err := repoCreateOutput(nil); err == nil {
        t.Fatal("expected an error for a nil repo, got nil")
    }
}

func TestRepoCreateOutput_OmitsRemoteWhenUnresolvable(t *testing.T) {
    t.Parallel()
    // A still-provisioning repo may lack a path; omit the field rather than