golangci/golangci-lint · error

clean runtime version: %w

Error message

clean runtime version: %w

What it means

CheckGoVersion compares the Go language version golangci-lint was built with against the targeted version from the analyzed module's go.mod. Before comparing, it calls CleanRuntimeVersion, which extracts the go1.x token from runtime.Version(). This error wraps a CleanRuntimeVersion failure: the running binary's version string contains no 'go1.' token, typically a devel/tip build or a nonstandard toolchain. The underlying message is 'invalid Go runtime version: <string>'.

Source

Thrown at pkg/goutil/version.go:16

package goutil

import (
	"fmt"
	"go/version"
	"regexp"
	"runtime"
	"strings"

	hcversion "github.com/hashicorp/go-version"
)

func CheckGoVersion(goVersion string) error {
	rv, err := CleanRuntimeVersion()
	if err != nil {
		return fmt.Errorf("clean runtime version: %w", err)
	}

	langVersion := version.Lang(rv)

	runtimeVersion, err := hcversion.NewVersion(strings.TrimPrefix(langVersion, "go"))
	if err != nil {
		return err
	}

	targetedVersion, err := hcversion.NewVersion(TrimGoVersion(goVersion))
	if err != nil {
		return err
	}

	if runtimeVersion.LessThan(targetedVersion) {
		return fmt.Errorf("the Go language version (%s) used to build golangci-lint is lower than the targeted Go version (%s)",
			langVersion, goVersion)
	}

View on GitHub (pinned to ed7a235d2d)

Solutions

  1. Use an official golangci-lint release built with a stable Go toolchain instead of a devel/tip build.
  2. If building from source, build with a released Go version so runtime.Version() contains a parseable 'go1.' token.
  3. Check the wrapped message after 'clean runtime version:' to identify the offending runtime string and toolchain.
  4. Align your go.mod go directive with a version <= the build toolchain's language version to avoid version-check paths.
  5. Report nonstandard version strings from forked toolchains upstream if they should be supported.

Example fix

// before
$ gotip build -o golangci-lint ./cmd/golangci-lint  // runtime.Version() = "devel ..." -> invalid
// after
$ go1.23 build -o golangci-lint ./cmd/golangci-lint  // stable toolchain, parseable version
Defensive patterns

Strategy: validation

Validate before calling

// Detect an unparseable runtime version before calling CheckGoVersion
func runtimeVersionIsClean() bool {
	for _, part := range strings.Fields(runtime.Version()) {
		if strings.HasPrefix(part, "go1.") {
			return true
		}
	}
	return false
}
// only use stable-toolchain builds if this returns false

Try / catch

if err := goutil.CheckGoVersion(targetedVersion); err != nil {
	if strings.Contains(err.Error(), "clean runtime version") {
		return fmt.Errorf("golangci-lint built with nonstandard Go toolchain (%s); rebuild with a stable release: %w", runtime.Version(), err)
	}
	return err
}

Prevention

When it happens

Trigger: Calling CheckGoVersion (via Load or an anonymous wrapper) with a golangci-lint binary whose runtime.Version() yields no 'go1.' token — e.g. gotip/devel builds like 'devel go1.24-e705a2d ...' in unparseable forms, or heavily forked toolchains.

Common situations: Using a gotip or source-built devel golangci-lint binary; running a binary built with a modified toolchain (custom crypto experiments, forked Go) against a module that requires a version check.

Related errors


AI-assisted analysis of golangci/golangci-lint@ed7a235d2d (2026-09-02). Data as JSON: /api/errors/fa03ac229f4ce1d3. Report an issue: GitHub.