Problem
make lint fails locally at the first Go target for anyone whose golangci-lint is older than the one CI uses:
$ make lint
...
Error: can't load config: the Go language version (go1.25) used to build golangci-lint is lower than the targeted Go version (1.26.1)
make[1]: *** [Makefile:42: lint] Error 3
make: *** [Makefile:211: lint-cli] Error 2
golangci-lint refuses to load .golangci.yml when the Go version it was built with is older than the go directive of the module it is linting. Our modules target go 1.26.1, so a golangci-lint built with go1.25.x is rejected outright.
Reproduced with golangci-lint 2.8.0 (built with go1.25.5, installed via go install), local Go 1.27.1, on unmodified main. It hits lint-cli and lint-schema-go identically. Because lint runs lint-cli first and make aborts there, the whole Python/TS half of the target never runs either — so one stale Go tool blocks linting for the entire repo, including contributors touching no Go at all.
Root cause
The version is pinned for CI but not for local development:
| Where |
golangci-lint version |
Pinned? |
.github/workflows/ci-cli.yaml |
v2.10.1 |
yes |
.github/workflows/ci-schema.yaml |
v2.10.1 |
yes |
.github/workflows/ci-sdk-go.yaml |
v2.10.1 |
yes |
.github/workflows/ci-sdk-go-postgres.yaml |
v2.10.1 |
yes |
Makefile / cli/Makefile / schema/Makefile / sdk/go/Makefile / sdk/go/stores/postgres/Makefile |
whatever is on PATH |
no |
The Makefiles all call bare golangci-lint run --fix -v, and DEVELOPMENT.md lists Python, uv, pnpm, Docker and Go under Prerequisites but never mentions golangci-lint. So there is nothing telling a contributor which version they need, and nothing that fails with a useful message when they have the wrong one — CI stays green while local lint is broken.
This is not a Go version problem: all five modules are coherent (cli, schema, sdk/go, sdk/go/stores/postgres on go 1.26.1; build/brew on go 1.26), CI derives its Go from go-version-file, and any Go >= 1.26.1 satisfies them. Only the linter is adrift.
Suggested fix
- Make local lint use the same version as CI, rather than whatever is installed — either run it through
go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION), or add an install/check target that errors with the required version when the binary on PATH is too old.
- Give the version a single source of truth.
v2.10.1 is currently duplicated across four workflow files plus (after 1) the Makefiles, so the next bump has five places to miss.
- Add golangci-lint to the
DEVELOPMENT.md prerequisites with its minimum version.
Worth considering alongside: lint aborting on the first Go failure hides unrelated results. Letting the sub-targets all run (or splitting Go from non-Go) would mean a stale Go tool no longer blocks Python and TypeScript linting.
Minor, related
build/brew/go.mod is on go 1.26 while the other four modules are on go 1.26.1. Harmless today, but worth aligning while touching this.
Problem
make lintfails locally at the first Go target for anyone whosegolangci-lintis older than the one CI uses:golangci-lint refuses to load
.golangci.ymlwhen the Go version it was built with is older than thegodirective of the module it is linting. Our modules targetgo 1.26.1, so a golangci-lint built with go1.25.x is rejected outright.Reproduced with
golangci-lint2.8.0 (built with go1.25.5, installed viago install), local Go 1.27.1, on unmodifiedmain. It hitslint-cliandlint-schema-goidentically. Becauselintrunslint-clifirst and make aborts there, the whole Python/TS half of the target never runs either — so one stale Go tool blocks linting for the entire repo, including contributors touching no Go at all.Root cause
The version is pinned for CI but not for local development:
.github/workflows/ci-cli.yamlv2.10.1.github/workflows/ci-schema.yamlv2.10.1.github/workflows/ci-sdk-go.yamlv2.10.1.github/workflows/ci-sdk-go-postgres.yamlv2.10.1Makefile/cli/Makefile/schema/Makefile/sdk/go/Makefile/sdk/go/stores/postgres/MakefilePATHThe Makefiles all call bare
golangci-lint run --fix -v, andDEVELOPMENT.mdlists Python, uv, pnpm, Docker and Go under Prerequisites but never mentions golangci-lint. So there is nothing telling a contributor which version they need, and nothing that fails with a useful message when they have the wrong one — CI stays green while local lint is broken.This is not a Go version problem: all five modules are coherent (
cli,schema,sdk/go,sdk/go/stores/postgresongo 1.26.1;build/brewongo 1.26), CI derives its Go fromgo-version-file, and any Go >= 1.26.1 satisfies them. Only the linter is adrift.Suggested fix
go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION), or add an install/check target that errors with the required version when the binary onPATHis too old.v2.10.1is currently duplicated across four workflow files plus (after 1) the Makefiles, so the next bump has five places to miss.DEVELOPMENT.mdprerequisites with its minimum version.Worth considering alongside:
lintaborting on the first Go failure hides unrelated results. Letting the sub-targets all run (or splitting Go from non-Go) would mean a stale Go tool no longer blocks Python and TypeScript linting.Minor, related
build/brew/go.modis ongo 1.26while the other four modules are ongo 1.26.1. Harmless today, but worth aligning while touching this.