task doctor: assert build-Go >= GOROOT for every Go analysis tool the gate invokes #45

Open
opened 2026-09-08 19:45:07 +00:00 by mathias · 0 comments
Owner

Follow-up to infra#375 (closed 2026-09-08), which was the third recurrence of this class on koala. Brain: wiki/homelab/failures/golangci-lint-must-be-built-with-go-at-least-goroot-version.

The recurring failure

A Go source-analysis tool built with an older Go than GOROOT cannot read the stdlib's export data. It happens every time a rolling-release host bumps Go, and the error blames your own source file:

internal/analyst/aggregator.go:6:2: could not import time (... could not load export data:
  cannot decode "internal/goarch", export data version 4 is greater than maximum supported version 2)

Known instances so far: openbanking-api (2026-09-03), openbanking-api again (2026-09-06, via two sessions applying incompatible fixes to the same shared binary), cobalt-dingo (2026-09-08). Two errcheck findings reached CI in one session purely because the local gate was unavailable.

Why a doctor check is the right shape

Diagnosis takes ~20 minutes and the symptom points at the wrong place. Detection is one comparison: golangci-lint --version reports the Go it was built with, go version reports GOROOT.

Scope — not just the linter

infra#375's fix covered golangci-lint and task check went green, but govulncheck v1.2.0 was still stale. Its symptom is worse precisely because it is quieter:

Tool Symptom when build-Go < GOROOT
golangci-lint Hard panic. Loud, blocks the gate, gets fixed
govulncheck Warning, then continues. Green gate, degraded analysis

So the check should iterate over every Go analysis tool the gate invokes and report each one's build-Go against GOROOT. The tools that only warn are exactly the ones that rot unnoticed, so they are the reason to build this rather than remember the golangci-lint case.

Suggested behaviour

  • For each of golangci-lint, govulncheck (extensible list): parse its reported build-Go, compare to go version.
  • Report per tool, and fail task doctor when any is older than GOROOT.
  • Name the fix in the output (go install <tool>@latest) so it is actionable without a search.

Caveat worth encoding in the message

The brain entry records that go install @latest and GOTOOLCHAIN pinning are two different fixes for the same mismatch, and that they stomp on each other via the shared ~/go/bin — that is what caused the 2026-09-06 recurrence. The doctor output should say which fix it is recommending and why, rather than just "upgrade", so two sessions do not alternate between them.

Related nuance for the implementation

/usr/local/bin precedes ~/go/bin in PATH on koala, so a tool present in both may look shadowed when it is actually a symlink. Resolve with readlink -f before reporting a mismatch, or the check will produce false positives.


Created via git-mcp on behalf of @mathias

Follow-up to infra#375 (closed 2026-09-08), which was the **third** recurrence of this class on koala. Brain: `wiki/homelab/failures/golangci-lint-must-be-built-with-go-at-least-goroot-version`. ## The recurring failure A Go source-analysis tool built with an older Go than GOROOT cannot read the stdlib's export data. It happens every time a rolling-release host bumps Go, and the error blames your own source file: ``` internal/analyst/aggregator.go:6:2: could not import time (... could not load export data: cannot decode "internal/goarch", export data version 4 is greater than maximum supported version 2) ``` Known instances so far: openbanking-api (2026-09-03), openbanking-api again (2026-09-06, via two sessions applying incompatible fixes to the same shared binary), cobalt-dingo (2026-09-08). Two `errcheck` findings reached CI in one session purely because the local gate was unavailable. ## Why a doctor check is the right shape Diagnosis takes ~20 minutes and the symptom points at the wrong place. Detection is **one comparison**: `golangci-lint --version` reports the Go it was built with, `go version` reports GOROOT. ## Scope — not just the linter infra#375's fix covered golangci-lint and `task check` went green, but `govulncheck` v1.2.0 was still stale. Its symptom is worse precisely because it is quieter: | Tool | Symptom when build-Go < GOROOT | |---|---| | golangci-lint | Hard panic. Loud, blocks the gate, gets fixed | | govulncheck | Warning, then continues. **Green gate, degraded analysis** | So the check should iterate over **every Go analysis tool the gate invokes** and report each one's build-Go against GOROOT. The tools that only warn are exactly the ones that rot unnoticed, so they are the reason to build this rather than remember the golangci-lint case. ## Suggested behaviour - For each of `golangci-lint`, `govulncheck` (extensible list): parse its reported build-Go, compare to `go version`. - Report per tool, and fail `task doctor` when any is older than GOROOT. - Name the fix in the output (`go install <tool>@latest`) so it is actionable without a search. ## Caveat worth encoding in the message The brain entry records that `go install @latest` and `GOTOOLCHAIN` pinning are **two different fixes for the same mismatch**, and that they stomp on each other via the shared `~/go/bin` — that is what caused the 2026-09-06 recurrence. The doctor output should say which fix it is recommending and why, rather than just "upgrade", so two sessions do not alternate between them. ## Related nuance for the implementation `/usr/local/bin` precedes `~/go/bin` in PATH on koala, so a tool present in both may look shadowed when it is actually a symlink. Resolve with `readlink -f` before reporting a mismatch, or the check will produce false positives. --- _Created via git-mcp on behalf of @mathias_
mathias added the risk/lowsize/stype/feat labels 2026-09-16 22:21:55 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mathias/skills#45