Request: Don't break Windows dev environment out of the box

Years ago, Go started having trouble compiling and installing applications on native Windows environments (Command Prompt, PowerShell, not Cygwin-like or WSL environments).

The go mod vendor system sometimes malfunctions in Windows. go install [./...] reports an inability to look in the vendor directory to fulfill import dependencies.

In an attempt to resolve this, the user may try to run go clean -modcache. However, that command fails due to quirks for Windows users, as well as quirks for users who update Go versions. In fact, running go clean -modcache both fails, and also triggers go install [./...] to generate even more errors than before, since a broken go clean -modcache leaves the $GOPATH/pkg tree in such a poor state.

From Go 1.15 onward, an awkward, opt-in GODEBUG=modcacheunzipinplace=1 environment variable configuration is required to Windows Go application contributors to get commands like go clean -modcache and go install ./... to succeed. Then, applications are able to build in Windows (with precisely the same git contents for vendor/ as before).

That’s not an intuitive behavior out of the box. Let’s improve Go, so that Windows users can make use of the vendor system, without having to waste time troubleshooting errors and changing the default Go configuration.

One way to reduce risk of corruption between Go versions, is to mark the pkg directory with a helper file like $GOPATH/pkg/.go-touch to indicate the version of Go that last wrote to the directory tree. We could backport error handling to present warnings, or better yet, errors, in the event that an incompatible Go version tries to read or write from the directory tree. The incompatible versions would still be incompatible, but with safer error handling, in a way that empowers us to promote GODEBUG=modcacheunzipinplace=1 as the new default behavior, at least in Windows.

That being said, I recognize that we would like not to break past versions of Go wherever possible. To that end, another grander option is possible: Move the pkg location from $GOPATH/pkg to $GOPATH/<go-version>/pkg. Given that certain packages like x/tools linters often break API’s anyway, it seems reasonable to stop reusing a single global location for this directory. Make it relative to the Go version for safety and future compatibility.

Go 1.24 could do this. Or Go 1.25. Without sacrificing backwards compatibility with old, insecure Go versions.

In ASDF, this is perhaps less of an issue, not just because ASDF is primarily a UNIX, non-Windows version manager; But also because ASDF tends to automatically nest many Go elements within version-relative directories…

Perhaps this is possible with some snippets in the (fragile) psenv system, though that’s only for PowerShell, not Command Prompt.

Perhaps this is possible with direnv, which if memory serves has been prototyping some kind of Windows (PowerShell?) support at long last.

Ideally, such improvements are made directly in Go, available to as many coders and environments as possible.

1 Like

This is an interesting read. I wasn’t aware that Go has such weird problems on Windows.

If you can replicate this behavior consistently, and if you are sure it originates from Go and not from Windows or apps installed on Windows (especially, virus scanners), I’d suggest searching the Issue Tracker for existing issues and file a new issue if there is none yet.

But TBH, if this issue started years ago and has not yet been reported via the issue tracker, I’d reckon the problem is with Windows, not with Go.

1 Like

Windows supports the desired behavior.

Go refuses to set this behavior as the defaulf because a few people using ancient, insecure Go versions might experience a breaking change…

But the out of the box behavior already breaks compilation, for anyone using the go mod vendor system to safeguard against leftpad.