Repository navigation
cmd/go: go vet -trimpath with CGo pollutes cache with absolute paths under relative BuildIDs #81805
Description
Go version
go version go1.27.1 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='/home/jwebb/gocode/bin'
GOCACHE='/tmp/go-vet-worktrees.Jz1u78/cache'
GOCACHEPROG=''
GODEBUG=''
GOENV=''
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build3008632129=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/dev/null'
GOMODCACHE='/home/jwebb/gocode/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPACKAGESDRIVER=''
GOPATH='/home/jwebb/gocode'
GOPRIVATE=''
GOPROXY='off'
GOROOT='/home/jwebb/opt/go'
GOSUMDB='off'
GOTELEMETRY='local'
GOTELEMETRYDIR='/home/jwebb/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='local'
GOTOOLDIR='/home/jwebb/opt/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.27.1'
GOWORK='off'
PKG_CONFIG='pkg-config'What did you do?
Run this bash script:
#!/usr/bin/env bash
set -eu
# Isolate the normal disk cache and ignore Go/Git user configuration.
export GOENV=off GOFLAGS= GOWORK=off GOTOOLCHAIN=local CGO_ENABLED=1
export GOCACHEPROG= GOPROXY=off GOSUMDB=off GOPRIVATE=
export GIT_CONFIG_NOSYSTEM=1 GIT_CONFIG_GLOBAL=/dev/null
repro_dir=$(mktemp -d "${TMPDIR:-/tmp}/go-vet-worktrees.XXXXXX")
export GOCACHE="$repro_dir/cache"
printf 'Reproducer directory: %s\n' "$repro_dir"
go version
go env
git init -q "$repro_dir/consumer"
cat > "$repro_dir/consumer/go.mod" <<'EOF'
module example.com/cgocache
go 1.20
EOF
cat > "$repro_dir/consumer/cgo.go" <<'EOF'
package cgocache
import "C"
EOF
git -C "$repro_dir/consumer" add go.mod cgo.go
git -C "$repro_dir/consumer" -c user.name=Reproducer \
-c user.email=reproducer@example.com commit -qm initial
git -C "$repro_dir/consumer" worktree add --detach -q "$repro_dir/producer" HEAD
# Populate compilation artifacts, but no vet results, from the other worktree.
# (Same path would be hit by go vet, but we'd need a more complex reproducer to avoid the cached final result.)
go -C "$repro_dir/producer" test -trimpath -vet=off .
git -C "$repro_dir/consumer" worktree remove "$repro_dir/producer"
# This should use consumer/cgo.go, but tries to open producer/cgo.go.
go -C "$repro_dir/consumer" vet -trimpath .What did you see happen?
The final vet command tries to open the removed producer worktree's source file:
? example.com/cgocache [no test files]
example.com/cgocache: can't parse raw cgo file: open /tmp/go-vet-worktrees.XXXXXX/producer/cgo.go: no such file or directory
What did you expect to see?
go vet -trimpath should succeed using consumer/cgo.go. The package in the consumer worktree is complete and identical to the committed package that populated the cache. The producer worktree should no longer be needed.
Specifically what has happened here is that the generated *.cgo1.go file contains an absolute //line directive naming the producer's source file, i.e. no trimming. With vet -trimpath, its contribution to the cache key is trimmed, permitting reuse in the other worktree. The cgocall analyzer follows that directive when locating the original cgo source.
I'm using Git worktrees in the reproducer as it seems the most likely reason people will hit this, particularly as LLMs have made worktrees more popular. It also applies when using a shared build cache via GOCACHEPROG (our actual use case), or indeed simply maintaining multiple independent checkouts.
Note that simply disabling trimpath allows the build to succeed, but only due to vet no longer being able to share caching between trees, which becomes a build performance issue for large codebases.
Activity
gabyhelp commentedon Sep 28, 2026
Related Issues
Related Code Changes
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
prattmic commentedon Sep 29, 2026
cc @golang/command-line