golangci/golangci-lint · error
failed to get goenv: %w
Error message
failed to get goenv: %w
What it means
computeGoModSalt reads the GOMOD environment value via the goenv package to hash go.mod for cache keys; a goenv.Get failure is wrapped as "failed to get goenv". goenv shells out to / inspects the local Go toolchain, so this indicates the Go environment could not be interrogated.
Source
Thrown at pkg/commands/run.go:706
return nil, fmt.Errorf("failed to JSON marshal config linter settings: %w", err)
}
configData := bytes.NewBufferString("linters.settings=")
configData.Write(lintersSettingsBytes)
configData.WriteString("\nbuild-tags=%s" + strings.Join(cfg.Run.BuildTags, ","))
h := sha256.New()
if _, err := h.Write(configData.Bytes()); err != nil {
return nil, err
}
return h.Sum(nil), nil
}
func computeGoModSalt() (string, error) {
values, err := goenv.Get(context.Background(), goenv.GOMOD)
if err != nil {
return "", fmt.Errorf("failed to get goenv: %w", err)
}
goModPath := filepath.Clean(values[goenv.GOMOD])
data, err := os.ReadFile(goModPath)
if err != nil {
return "", fmt.Errorf("failed to read go.mod: %w", err)
}
// NOTE: the variable `goModPath` is not used here to ensure getting the same hash, independently of the location, for the same content.
sum, err := dirhash.Hash1([]string{"go.mod"}, func(string) (io.ReadCloser, error) {
return io.NopCloser(bytes.NewReader(data)), nil
})
if err != nil {
return "", fmt.Errorf("failed to compute go.sum: %w", err)
}
return sum, nilView on GitHub (pinned to ed7a235d2d)
Solutions
- Ensure the `go` toolchain is installed and on PATH (`which go`, `go version`).
- Run from within a Go module directory; the code only warns on missing go.mod, but goenv itself must still succeed.
- In minimal Docker images, keep the go binary or run the lint stage in a full Go image (e.g. golang:1.x).
- Fix corrupted Go installations (reinstall the toolchain) if `go env` itself errors.
- Check inherited GOFLAGS/GO111MODULE values that could make `go env` fail.
Example fix
// before (Dockerfile) FROM alpine COPY golangci-lint /usr/bin/ # no go toolchain -> goenv fails // after FROM golang:1.22 COPY golangci-lint /usr/bin/
Defensive patterns
Strategy: validation
Validate before calling
if _, err := exec.LookPath("go"); err != nil {
return fmt.Errorf("go toolchain not on PATH; goenv (and cache salt) will fail")
}
if err := exec.Command("go", "version").Run(); err != nil {
return fmt.Errorf("go binary present but broken: %w", err)
} Try / catch
if err := cmd.Run(); err != nil && strings.Contains(err.Error(), "failed to get goenv") {
log.Fatalf("ensure `go` is installed and on PATH: %v", err)
} Prevention
- Verify `go version` works in the same shell/CI step before linting.
- Use Go-inclusive base images (golang:1.x) for lint stages.
- Add /usr/local/go/bin to PATH in cron/systemd/non-interactive contexts.
- Reinstall a corrupted toolchain if `go env` itself errors.
When it happens
Trigger: goenv.Get(context.Background(), goenv.GOMOD) fails — typically the `go` binary is missing from PATH, or running `go env GOMOD` errors (broken Go installation, GOFLAGS/env problems, go unavailable in the sandbox).
Common situations: CI images without the Go toolchain installed (only the golangci-lint binary); restricted Docker images where the go binary was removed to shrink size; PATH not including /usr/local/go/bin in cron or systemd contexts.
Related errors
- failed to build packages cache: %w
- context loading failed: %w
- failed to calculate binary salt: %w
- failed to calculate config salt: %w
- failed to JSON marshal config linter settings: %w
AI-assisted analysis of golangci/golangci-lint@ed7a235d2d (2026-09-02).
Data as JSON: /api/errors/266a20b3f68d462a.
Report an issue: GitHub.