Skip to content

test: load through helpers that cannot return nil - #141

Merged
Ilyes512 merged 1 commit into
chore/prune-unnecessary-commentsfrom
chore/fix-staticcheck-nil-deref
Sep 4, 2026
Merged

test: load through helpers that cannot return nil#141
Ilyes512 merged 1 commit into
chore/prune-unnecessary-commentsfrom
chore/fix-staticcheck-nil-deref

Conversation

@Ilyes512

@Ilyes512 Ilyes512 commented Sep 4, 2026

Copy link
Copy Markdown
Member

Top of the stack on #140. Test-only — no production code changes.

The finding

LoadMetadata, LoadStatus and registry.Load all report an absent file as (nil, nil), so every caller has to check the pointer before reading it. Nine test sites wrote that check out by hand, and staticcheck flags each as SA5011: possible nil pointer dereference — it does not model t.Fatal as ending the test, so it sees a nil check followed by an unguarded read.

The check is correct. But writing it nine times is what put it in front of the linter nine times. Each package now gains one mustLoad… helper that fails the test when the value is absent and otherwise returns a pointer known to be non-nil — a contract a caller cannot get wrong, and one the analyser has no reason to question. It also drops 4 lines of boilerplate per site.

Why it did not show up in CI

Same golangci-lint (v2.12.2) and same config in both places; the difference is the Go toolchain. CI pins Go from go.mod via GOTOOLCHAIN: local (1.26.1) and reports 0 issues. The golangci/golangci-lint:v2.12.2-alpine image that task lint uses ships 1.26.2, where the same staticcheck build reaches a different conclusion on these nine sites.

So it is a false positive today, but a latent CI failure the moment go.mod is bumped to 1.26.2 — reason enough to resolve it rather than suppress it with //nolint or a config exclusion.

Scope note

task lint originally reported only 6 findings because golangci-lint caps duplicates (max-same-issues). Running with --max-same-issues=0 --max-issues-per-linter=0 showed 17 across 5 files, which is what this fixes; that same command now reports 0 issues.

Checks

task lint (and the uncapped variant), go test -race, go test -tags=integration -race ./internal/cmd/..., gofmt and go build all clean.

Because a helper that silently returned a zero value would make these tests pass vacuously, I mutation-checked it: breaking LoadMetadata's Updated-to-Created fallback makes TestLoadMetadata_MissingUpdated_FallsBackToCreated fail as it should.


Stack created with GitHub Stacks CLIGive Feedback 💬

LoadMetadata, LoadStatus and registry.Load all report an absent file as
(nil, nil), so every caller has to check the pointer before reading it. Nine
test sites wrote that check out by hand, and staticcheck flags each of them as
a possible nil dereference: it does not model t.Fatal as ending the test, so
it sees a nil check followed by an unguarded read.

The check is correct, but writing it nine times is what put it in front of the
linter nine times. Each package gains one must-load helper that fails the test
when the value is absent and otherwise returns a pointer known to be non-nil,
which is a contract a caller cannot get wrong and the analyser has no reason
to question.

Only local golangci-lint sees this today. CI pins Go from go.mod (1.26.1) and
reports no issues; the container ships 1.26.2, where the same staticcheck
build reaches a different conclusion. The finding therefore lands in CI the
moment go.mod is bumped, which is reason enough to resolve it rather than
suppress it.

No production code changes. Verified the assertions still bite by breaking
LoadMetadata's Updated-to-Created fallback and watching the round-trip test
fail.
@Ilyes512
Ilyes512 force-pushed the chore/fix-staticcheck-nil-deref branch from 9f8f832 to f377207 Compare September 4, 2026 08:45
@Ilyes512
Ilyes512 merged commit 2ae6e40 into main Sep 4, 2026
5 of 10 checks passed
@Ilyes512
Ilyes512 deleted the chore/fix-staticcheck-nil-deref branch September 4, 2026 10:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant