Summary
When rtk wraps go build and the build fails due to a package-pattern / module-resolution error (not a compile error), rtk prints Go build: Success even though the wrapped go build exited non-zero (1) and wrote an error to stderr. The "Success" text directly contradicts the preserved exit code, and the real error message is swallowed.
Compile errors are handled correctly — only this class of non-compile build failures is misreported.
Environment
- rtk:
0.41.0
- go:
go1.26.2
- OS:
darwin/arm64
Minimal reproduction (self-contained, no project needed)
mkdir -p /tmp/rtk-nomod && cd /tmp/rtk-nomod # empty dir, no go.mod
# real output (bypassing rtk's filter via `rtk proxy`):
rtk proxy go build ./...
# => pattern ./...: directory prefix . does not contain main module or its selected dependencies
# => exit 1
# through rtk:
rtk go build ./...
# => Go build: Success <-- BUG: contradicts the failure
# => exit 1 (exit code is correctly preserved)
Also reproduces at a Go workspace (go.work) root that has no module of its own:
rtk proxy go build ./...
# pattern ./...: directory prefix . does not contain modules listed in go.work or their selected dependencies (exit 1)
rtk go build ./...
# Go build: Success (exit 1)
Contrast: real compile errors ARE handled correctly
mkdir -p /tmp/rtk-repro && cd /tmp/rtk-repro
printf 'package main\nfunc main() { thisFunctionDoesNotExist() }\n' > main.go
go mod init rtkrepro
rtk go build .
# Go build: 1 errors
# 1. ./main.go:2:14: undefined: thisFunctionDoesNotExist (exit 1) -- correct
So the formatter correctly detects file:line: compile diagnostics, but when go build fails with a pattern / module-resolution error on stderr (which doesn't match the compile-diagnostic shape), it falls through to the default "Success" message and discards both the stderr content and the signal of the non-zero exit.
Expected behavior
- Never print
Go build: Success when the wrapped command exits non-zero.
- Gate the "Success" branch on the child process exit code (
== 0), not solely on whether compile-diagnostic lines were parsed from stdout.
- On failure, surface the real stderr (e.g. the
pattern ./...: message), or at least emit something like Go build: failed (exit 1).
Impact
rtk targets LLM / terminal agent sessions. Running go build ./... from a Go workspace (go.work) root is a very common operation; the build fails with a pattern error, but the agent reads Go build: Success and proceeds on a false premise. The misreport contradicts the exit code and hides the actual cause of the failure.
Summary
When
rtkwrapsgo buildand the build fails due to a package-pattern / module-resolution error (not a compile error),rtkprintsGo build: Successeven though the wrappedgo buildexited non-zero (1) and wrote an error to stderr. The "Success" text directly contradicts the preserved exit code, and the real error message is swallowed.Compile errors are handled correctly — only this class of non-compile build failures is misreported.
Environment
0.41.0go1.26.2darwin/arm64Minimal reproduction (self-contained, no project needed)
Also reproduces at a Go workspace (
go.work) root that has no module of its own:Contrast: real compile errors ARE handled correctly
So the formatter correctly detects
file:line:compile diagnostics, but whengo buildfails with a pattern / module-resolution error on stderr (which doesn't match the compile-diagnostic shape), it falls through to the default "Success" message and discards both the stderr content and the signal of the non-zero exit.Expected behavior
Go build: Successwhen the wrapped command exits non-zero.== 0), not solely on whether compile-diagnostic lines were parsed from stdout.pattern ./...:message), or at least emit something likeGo build: failed (exit 1).Impact
rtktargets LLM / terminal agent sessions. Runninggo build ./...from a Go workspace (go.work) root is a very common operation; the build fails with a pattern error, but the agent readsGo build: Successand proceeds on a false premise. The misreport contradicts the exit code and hides the actual cause of the failure.