What version of Go, VS Code & VS Code Go extension are you using?
Version Information
- Run
go version to get version of Go from the VS Code integrated terminal.
- go version go1.25.3 X:nodwarf5 linux/amd64
- Run
gopls -v version to get version of Gopls from the VS Code integrated terminal.
- golang.org/x/tools/gopls v0.21.1 go: go1.25.3 X:jsonv2
- Run
code -v or code-insiders -v to get version of VS Code or VS Code Insiders.
- 1.106.3 bf9252a2fb45be6893dd8870c0bf37e2e1766d61 x64
- Check your installed extensions to get the version of the VS Code Go extension
- Run Ctrl+Shift+P (Cmd+Shift+P on Mac OS) >
Go: Locate Configured Go Tools command.
Tools Configuration
Environment
GOBIN: undefined
toolsGopath:
gopath: /home/firelizzard/go
GOROOT: /usr/lib/go
PATH: /usr/local/sbin:/usr/local/bin:/usr/bin:/opt/bin:/usr/lib/llvm/20/bin
Tools
go: /usr/bin/go: go version go1.25.3 X:nodwarf5 linux/amd64
gotests: /home/firelizzard/go/bin/gotests (version: v1.6.0 built with go: go1.25.0)
impl: /home/firelizzard/go/bin/impl (version: v1.4.0 built with go: go1.25.0)
goplay: /home/firelizzard/go/bin/goplay (version: v1.0.0 built with go: go1.25.0)
dlv: /home/firelizzard/go/bin/dlv (version: v1.26.0 built with go: go1.25.3)
golint: /home/firelizzard/go/bin/golint (version: v0.0.0-20241112194109-818c5a804067 built with go: go1.25.0)
gopls: /home/firelizzard/go/bin/gopls (version: v0.21.1 built with go: go1.25.3)
Go env
Workspace Folder (vscode-go): /home/firelizzard/src/golang/vscode-go
AR='ar'
CC='x86_64-pc-linux-gnu-gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='x86_64-pc-linux-gnu-g++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/home/firelizzard/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/home/firelizzard/.config/go/env'
GOEXE=''
GOEXPERIMENT='jsonv2'
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build1554880090=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/home/firelizzard/src/golang/vscode-go/go.mod'
GOMODCACHE='/home/firelizzard/go/pkg/mod'
GONOPROXY='github.com/C3Rules/Go-DTRules'
GONOSUMDB='github.com/C3Rules/Go-DTRules'
GOOS='linux'
GOPATH='/home/firelizzard/go'
GOPRIVATE='github.com/C3Rules/Go-DTRules'
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/lib/go'
GOSUMDB='sum.golang.org'
GOTELEMETRY='on'
GOTELEMETRYDIR='/home/firelizzard/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='local'
GOTOOLDIR='/usr/lib/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.25.3 X:nodwarf5'
GOWORK=''
PKG_CONFIG='pkg-config'
Describe the bug
When a launch configuration has "mode": "auto" and "program" set to a directory, the extension infers whether to use debug or test mode by checking if the active editor's file ends with _test.go. The program field is ignored for this inference.
This means a named launch configuration targeting a specific directory will sometimes launch as a test binary and sometimes as a debug binary, depending on which file happens to be focused in the editor when the session starts — even if that file is in a completely unrelated package.
Expected behavior: When program is set to a directory, mode: auto should default to debug. The active editor file is irrelevant when an explicit target is specified.
Actual behavior: If any _test.go file is active in the editor, the extension sends mode: test to Delve regardless of the program field. If the target package has no test files, Delve produces an empty binary and the launch fails with not an executable file.
The offending code is here:
|
if (debugConfiguration['mode'] === 'auto') { |
|
let filename = activeEditor?.document?.fileName; |
|
if (debugConfiguration['program'] && debugConfiguration['program'].endsWith('.go')) { |
|
// If the 'program' attribute is a file, not a directory, then we will determine the mode from that |
|
// file path instead of the currently active file. |
|
filename = debugConfiguration['program']; |
|
} |
|
debugConfiguration['mode'] = filename?.endsWith('_test.go') ? 'test' : 'debug'; |
|
} |
The code only substitutes program for the active filename when program ends in .go. When program is a directory (the common case), the active editor file is used unconditionally.
I confirmed this by running the extension in extension host debug mode, observing the incorrect mode: test being sent to Delve, then making debugConfiguration['mode'] = 'debug' unconditional and confirming the issue was gone.
Steps to reproduce the behavior
- Create a launch configuration with
"mode": "auto" and "program": "${workspaceFolder}" pointing at a package with no test files
- Open any
_test.go file from another package in the editor so it is the active tab
- Run the launch configuration
- Observe that Delve receives
mode: test, attempts to compile a test binary for the target package, produces an empty file, and fails with not an executable file
See also go-delve/delve#4229
What version of Go, VS Code & VS Code Go extension are you using?
Version Information
go versionto get version of Go from the VS Code integrated terminal.gopls -v versionto get version of Gopls from the VS Code integrated terminal.code -vorcode-insiders -vto get version of VS Code or VS Code Insiders.Go: Locate Configured Go Toolscommand.Tools Configuration
Environment
GOBIN: undefined
toolsGopath:
gopath: /home/firelizzard/go
GOROOT: /usr/lib/go
PATH: /usr/local/sbin:/usr/local/bin:/usr/bin:/opt/bin:/usr/lib/llvm/20/bin
Tools
Go env
Workspace Folder (vscode-go): /home/firelizzard/src/golang/vscode-go
Describe the bug
When a launch configuration has
"mode": "auto"and"program"set to a directory, the extension infers whether to usedebugortestmode by checking if the active editor's file ends with_test.go. Theprogramfield is ignored for this inference.This means a named launch configuration targeting a specific directory will sometimes launch as a test binary and sometimes as a debug binary, depending on which file happens to be focused in the editor when the session starts — even if that file is in a completely unrelated package.
Expected behavior: When
programis set to a directory,mode: autoshould default todebug. The active editor file is irrelevant when an explicit target is specified.Actual behavior: If any
_test.gofile is active in the editor, the extension sendsmode: testto Delve regardless of theprogramfield. If the target package has no test files, Delve produces an empty binary and the launch fails withnot an executable file.The offending code is here:
vscode-go/extension/src/goDebugConfiguration.ts
Lines 337 to 345 in 80370ef
The code only substitutes
programfor the active filename whenprogramends in.go. Whenprogramis a directory (the common case), the active editor file is used unconditionally.I confirmed this by running the extension in extension host debug mode, observing the incorrect
mode: testbeing sent to Delve, then makingdebugConfiguration['mode'] = 'debug'unconditional and confirming the issue was gone.Steps to reproduce the behavior
"mode": "auto"and"program": "${workspaceFolder}"pointing at a package with no test files_test.gofile from another package in the editor so it is the active tabmode: test, attempts to compile a test binary for the target package, produces an empty file, and fails withnot an executable fileSee also go-delve/delve#4229