golangci/golangci-lint · error
%w
Error message
%w
What it means
Env.Discover reads GOCACHE and GOROOT by invoking the go toolchain via goenv.Get (grignotin/goenv). This error is returned when that call fails: the go binary could not be executed, its output could not be parsed, or the context was canceled. The raw error is re-wrapped verbatim with fmt.Errorf("%w", err), so the root cause appears directly in the message.
Source
Thrown at pkg/goutil/env.go:34
type Env struct {
vars map[string]string
log logutils.Log
}
func NewEnv(log logutils.Log) *Env {
return &Env{
vars: map[string]string{},
log: log,
}
}
func (e Env) Discover(ctx context.Context) error {
startedAt := time.Now()
var err error
e.vars, err = goenv.Get(ctx, goenv.GOCACHE, goenv.GOROOT)
if err != nil {
return fmt.Errorf("%w", err)
}
e.log.Infof("Read go env for %s: %#v", time.Since(startedAt), e.vars)
return nil
}
func (e Env) Get(k EnvKey) string {
envValue := os.Getenv(string(k))
if envValue != "" {
return envValue
}
return e.vars[string(k)]
}
View on GitHub (pinned to ed7a235d2d)
Solutions
- Verify `go env GOCACHE GOROOT` succeeds in the same shell/environment where golangci-lint runs.
- Install the Go toolchain and ensure it is on PATH inside the container/CI job running the linter.
- Check GOENV, GOFLAGS, GOPROXY and GOCACHE environment variables for invalid or conflicting values.
- Run with verbose logging to surface the wrapped root cause if the message is opaque.
- As a last resort, reinstall a supported Go version and clear GOCACHE (`go clean -cache`).
Example fix
# before (CI image without a toolchain) image: golangci/golangci-lint:latest # no go installed, `go env` fails # after image: golang:1.23 script: - go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest - golangci-lint run
Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure the go toolchain is usable before invoking the linter
func checkGoToolchain() error {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if out, err := exec.CommandContext(ctx, "go", "env", "GOCACHE", "GOROOT").Output(); err != nil {
return fmt.Errorf("go toolchain unavailable: %w", err)
} else {
_ = out
}
return nil
} Try / catch
env := goutil.NewEnv(log)
if err := env.Discover(ctx); err != nil {
if errors.Is(err, context.DeadlineExceeded) {
return fmt.Errorf("go env timed out; check GOFLAGS/proxy settings: %w", err)
}
return fmt.Errorf("cannot read go env (is Go installed and on PATH?): %w", err)
} Prevention
- Install the Go toolchain in every container/CI image that runs golangci-lint.
- Verify `go env GOCACHE GOROOT` succeeds in the same environment before linting.
- Keep GOCACHE writable and GOENV/GOFLAGS free of conflicting values.
- Set reasonable context timeouts for go env discovery.
When it happens
Trigger: Calling Discover (directly or via runAndPrint during a golangci-lint run) when the go binary is missing from PATH, the Go version is too old or its `go env` output format is unexpected, GOCACHE/GOROOT point to invalid locations, `go env` exits non-zero, or ctx is canceled before goenv.Get completes.
Common situations: Running golangci-lint in a Docker/CI image without the Go toolchain; GOENV/GOFLAGS misconfiguration breaking `go env`; GOCACHE pointing to a non-writable path; a broken Go installation after an upgrade.
Related errors
- clean runtime version: %w
- the Go language version (%s) used to build golangci-lint is
- failed to get goenv: %w
- can't scan file %s: %w
- makezero linter failed on file %q: %w
AI-assisted analysis of golangci/golangci-lint@ed7a235d2d (2026-09-02).
Data as JSON: /api/errors/9cc83c6ef3d9fb03.
Report an issue: GitHub.