Summary
rtk golangci-lint run prints the (correctly filtered) lint findings but exits 0 even when golangci-lint found issues and the raw binary would exit 1. The non-zero exit code is swallowed.
This is especially impactful because the Claude Code hook auto-rewrites golangci-lint run ... → rtk golangci-lint run .... So any exit-code-based gate — pre-commit hooks, Makefile targets, && chains, and AI-agent "did lint pass?" checks — sees success while lint actually failed. The findings are visible in the output, but automation (and agents reasoning over exit codes) is misled into thinking the tree is clean.
Environment
- rtk 0.42.4
- golangci-lint 2.12.2 (config
version: "2")
- macOS (darwin, arm64)
Reproduce
T=$(mktemp -d) && cd "$T" && go mod init lintcheck >/dev/null
printf 'package main\n\nfunc main() {\n\tx := 1\n\tx = 2\n\t_ = x\n}\n' > main.go
printf 'version: "2"\nlinters:\n default: none\n enable: [ineffassign]\n' > .golangci.yml
rtk golangci-lint run ./... ; echo "rtk filtered -> exit=$?"
rtk proxy golangci-lint run ./... ; echo "rtk proxy -> exit=$?"
golangci-lint run ./... ; echo "direct binary -> exit=$?"
Observed:
rtk filtered -> exit=0 <-- masked (issue is printed, but exit says success)
rtk proxy -> exit=1
direct binary -> exit=1
Expected
rtk golangci-lint run should propagate golangci-lint's exit code (1 when issues are found, 0 when clean) while keeping the compact output.
Scope (what I verified)
Only the golangci-lint handler is affected. These all propagate exit codes correctly:
rtk go test → 1 on test failure
rtk go build → 1 on compile error
rtk go vet → 1 on vet error
rtk grep → propagates
Workaround
Add golangci-lint to the hook exclude list so it runs raw (output is small, so ~no token cost):
[hooks]
exclude_commands = ["golangci-lint"]
Related
Likely a concrete instance of the concern in #1313 (honest account of silent failures in agent contexts). Distinct here: it's exit-code propagation, not output truncation.
Summary
rtk golangci-lint runprints the (correctly filtered) lint findings but exits 0 even when golangci-lint found issues and the raw binary would exit 1. The non-zero exit code is swallowed.This is especially impactful because the Claude Code hook auto-rewrites
golangci-lint run ...→rtk golangci-lint run .... So any exit-code-based gate — pre-commit hooks, Makefile targets,&&chains, and AI-agent "did lint pass?" checks — sees success while lint actually failed. The findings are visible in the output, but automation (and agents reasoning over exit codes) is misled into thinking the tree is clean.Environment
version: "2")Reproduce
Observed:
Expected
rtk golangci-lint runshould propagate golangci-lint's exit code (1 when issues are found, 0 when clean) while keeping the compact output.Scope (what I verified)
Only the
golangci-linthandler is affected. These all propagate exit codes correctly:rtk go test→ 1 on test failurertk go build→ 1 on compile errorrtk go vet→ 1 on vet errorrtk grep→ propagatesWorkaround
Add golangci-lint to the hook exclude list so it runs raw (output is small, so ~no token cost):
Related
Likely a concrete instance of the concern in #1313 (honest account of silent failures in agent contexts). Distinct here: it's exit-code propagation, not output truncation.