test: load through helpers that cannot return nil - #141
Merged
Ilyes512 merged 1 commit intoSep 4, 2026
Conversation
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
force-pushed
the
chore/fix-staticcheck-nil-deref
branch
from
September 4, 2026 08:45
9f8f832 to
f377207
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Top of the stack on #140. Test-only — no production code changes.
The finding
LoadMetadata,LoadStatusandregistry.Loadall 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 asSA5011: possible nil pointer dereference— it does not modelt.Fatalas 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.modviaGOTOOLCHAIN: local(1.26.1) and reports0 issues. Thegolangci/golangci-lint:v2.12.2-alpineimage thattask lintuses 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.modis bumped to 1.26.2 — reason enough to resolve it rather than suppress it with//nolintor a config exclusion.Scope note
task lintoriginally reported only 6 findings because golangci-lint caps duplicates (max-same-issues). Running with--max-same-issues=0 --max-issues-per-linter=0showed 17 across 5 files, which is what this fixes; that same command now reports0 issues.Checks
task lint(and the uncapped variant),go test -race,go test -tags=integration -race ./internal/cmd/...,gofmtandgo buildall 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 makesTestLoadMetadata_MissingUpdated_FallsBackToCreatedfail as it should.Stack created with GitHub Stacks CLI • Give Feedback 💬