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
cmd/entire/cli
Mrepo.go+4
- Mrepo_test.go+10
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