Go version
go version go1.26.3 linux/amd64
Output of go env in your module/workspace:
AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/u/bushnell/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/u/bushnell/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build2214924246=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/dev/null'
GOMODCACHE='/u/bushnell/go/pkg/mod'
GONOPROXY='*.deshaw.com'
GONOSUMDB='*.deshaw.com'
GOOS='linux'
GOPATH='/u/bushnell/go'
GOPRIVATE='*.deshaw.com'
GOPROXY='https://bushnell:yo80jomsa%23Td9qQlkrryBOiNDoGt98E%26%29s%21rxbzHGrh%40iB%24G2gf2797YGfF%29FMk8@artifactory.deshaw.com/artifactory/api/go/go'
GOROOT='/proj/lang/go/1.26.3/x86_64'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/u/bushnell/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/proj/lang/go/1.26.3/x86_64/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.26.3'
GOWORK=''
PKG_CONFIG='pkg-config'
What did you do?
Run a passing test binary which writes output that does not end with a newline (typically a stderr diagnostic that uses %q or otherwise forgets the trailing \n), go test — in non-verbose, non-JSON mode. See this example:
// blank_test.go
package blanklinerepro
import (
"fmt"
"os"
"testing"
)
func TestPass(t *testing.T) {}
func TestMain(m *testing.M) {
code := m.Run()
// Last write to stderr doesn't end in '\n'. %q is a common way to land here:
// it emits a closing '"' as the final byte.
fmt.Fprintf(os.Stderr, "teardown problem: %q", "some detail")
os.Exit(code)
}
Tested with go version go1.26.3 linux/amd64. The relevant cmd/go code is unchanged on tip, so this almost certainly reproduces on every Go version since the linked CL landed.
We hit this in the wild when a teardown helper in our test infrastructure was calling something like this (note that despite the output, the tests were correctly passing):
fmt.Fprintf(os.Stderr, "failing output from subprocess: %v:\n%q", err, string(errout))
note format ending in %q, no trailing \n. When we used this helper in TestMain for some packages, every go test ./... run produced a stray blank line in front of those packages' ok lines, baked into the test cache. We fixed our format string locally, but the underlying cmd/go behavior was surprising and seems worth correcting upstream.
What did you see happen?
Running the test emits a blank line in front of the ok pkg T.TTTs summary line, with nothing above it. The captured output itself is correctly suppressed (the test passed), so the blank line is a separator dangling in front of empty space. The result is cached, so the blank line keeps reappearing on every cache hit.
$ go test -count=1 ./...
<-- blank line
ok blanklinerepro 0.004s
$ go test -count=1 ./... | xxd | head -1
00000000: 0a 6f 6b 20 20 09 62 6c 61 6e 6b 6c 69 6e 65 72 .ok .blankliner
<LF>ok blanklinerepro 0.004s<LF>
What did you expect to see?
A passing, non-verbose run whose captured output is being suppressed should print:
with no leading blank line. The separator only makes sense when there is visible output above the ok line that needs to be ended with a newline.
Go version
go version go1.26.3 linux/amd64
Output of
go envin your module/workspace:What did you do?
Run a passing test binary which writes output that does not end with a newline (typically a stderr diagnostic that uses
%qor otherwise forgets the trailing\n),go test— in non-verbose, non-JSON mode. See this example:Tested with
go version go1.26.3 linux/amd64. The relevantcmd/gocode is unchanged on tip, so this almost certainly reproduces on every Go version since the linked CL landed.We hit this in the wild when a teardown helper in our test infrastructure was calling something like this (note that despite the output, the tests were correctly passing):
note format ending in
%q, no trailing\n. When we used this helper inTestMainfor some packages, everygo test ./...run produced a stray blank line in front of those packages'oklines, baked into the test cache. We fixed our format string locally, but the underlyingcmd/gobehavior was surprising and seems worth correcting upstream.What did you see happen?
Running the test emits a blank line in front of the
ok pkg T.TTTssummary line, with nothing above it. The captured output itself is correctly suppressed (the test passed), so the blank line is a separator dangling in front of empty space. The result is cached, so the blank line keeps reappearing on every cache hit.What did you expect to see?
A passing, non-verbose run whose captured output is being suppressed should print:
with no leading blank line. The separator only makes sense when there is visible output above the
okline that needs to be ended with a newline.