{"record":{"id":"0c80d46b3892d8dc","repo":"golang/go","slug":"invalid-s-version-s","errorCode":null,"errorMessage":"invalid %s version %s","messagePattern":"invalid (.+?) version (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/modfetch/toolchain.go","lineNumber":99,"sourceCode":"\tversions.List = list\n\treturn versions, nil\n}\n\nfunc (r *toolchainRepo) Stat(ctx context.Context, rev string) (*RevInfo, error) {\n\t// Convert rev to DL version and stat that to make sure it exists.\n\t// In theory the go@ versions should be like 1.21.0\n\t// and the toolchain@ versions should be like go1.21.0\n\t// but people will type the wrong one, and so we accept\n\t// both and silently correct it to the standard form.\n\tprefix := \"\"\n\tv := rev\n\tv = strings.TrimPrefix(v, \"go\")\n\tif r.path == \"toolchain\" {\n\t\tprefix = \"go\"\n\t}\n\n\tif !gover.IsValid(v) {\n\t\treturn nil, fmt.Errorf(\"invalid %s version %s\", r.path, rev)\n\t}\n\n\t// If we're asking about \"go\" (not \"toolchain\"), pretend to have\n\t// all earlier Go versions available without network access:\n\t// we will provide those ourselves, at least in GOTOOLCHAIN=auto mode.\n\tif r.path == \"go\" && gover.Compare(v, gover.Local()) <= 0 {\n\t\treturn &RevInfo{Version: prefix + v}, nil\n\t}\n\n\t// Similarly, if we're asking about *exactly* the current toolchain,\n\t// we don't need to access the network to know that it exists.\n\tif r.path == \"toolchain\" && v == gover.Local() {\n\t\treturn &RevInfo{Version: prefix + v}, nil\n\t}\n\n\tif gover.IsLang(v) {\n\t\t// We can only use a language (development) version if the current toolchain\n\t\t// implements that version, and the two checks above have ruled that out.","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/modfetch/toolchain.go#L81-L117","documentation":"This error is thrown when resolving a 'go' or 'toolchain' module version and the revision string doesn't pass gover.IsValid validation. After stripping the 'go' prefix (e.g., 'go1.21.0' -> '1.21.0'), the remaining string must be a valid Go version. If it's malformed (e.g., '1.foo', '1.2.x', 'v1.21'), IsValid returns false and this error reports which module path (go or toolchain) and revision caused the failure.","triggerScenarios":"When go resolves a 'go@version' or 'toolchain@version' query (via go get go@1.21, GOTOOLCHAIN=go1.21.0+auto, or toolchain directive in go.mod). The revision is stripped of the 'go' prefix and checked with gover.IsValid. Invalid revisions like '1.2-beta' (should be '1.2.0-beta') or 'latest' (not a valid version for this code path) trigger this.","commonSituations":"A toolchain directive in go.mod specifies a malformed version. GOTOOLCHAIN is set to a non-standard version string. A user types 'go get go@1.foo' or 'go get toolchain@v1.21.0' (the 'v' prefix is invalid for Go versions). Confusion between semver ('v1.2.3') and Go version ('1.2.3') syntax.","solutions":["Use standard Go version syntax without the 'v' prefix: 'go get go@1.21.0' not 'go@v1.21.0'.","Include the full version: '1.21.0' not '1.21' for toolchain requests (language versions are handled separately).","Check the toolchain directive in go.mod: ensure it reads 'toolchain go1.21.0' with proper version format.","Validate the version string with 'go version' semantics: major.minor[.patch[.build]] with optional prerelease suffix."],"exampleFix":"# before\n$ go get toolchain@v1.21.0\n# invalid toolchain version v1.21.0\n\n# after: no 'v' prefix, standard Go version\n$ go get toolchain@go1.21.0\n# or simply\n$ go get go@1.21.0","handlingStrategy":"validation","validationCode":"// Validate Go version string before using in toolchain queries\nimport \"golang.org/x/mod/semver\"\n\nfunc validateGoVersion(rev string) error {\n    v := strings.TrimPrefix(rev, \"go\")\n    // Go versions don't use 'v' prefix\n    if strings.HasPrefix(v, \"v\") {\n        return fmt.Errorf(\"Go version must not have 'v' prefix: %s\", rev)\n    }\n    // Must match N.N or N.N.N pattern\n    matched, _ := regexp.MatchString(`^\\d+\\.\\d+(\\.\\d+)?(-[a-z0-9.]+)?$`, v)\n    if !matched {\n        return fmt.Errorf(\"invalid Go version: %s (expected format like 1.21.0)\", rev)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if strings.Contains(stderr, \"invalid \") && strings.Contains(stderr, \"version\") {\n    // Extract the invalid version from stderr and suggest the correct format\n    // Remove 'v' prefix, ensure N.N.N format\n}","preventionTips":["Go versions use '1.21.0' format, not semver 'v1.21.0'","Always strip 'v' prefix when specifying Go versions","Validate version strings with gover.IsValid equivalent before passing to toolchain commands","Use 'go version' to see valid version string format"],"tags":["go-toolchain","go-version","gotoolchain","validation"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}