golang/go · error
invalid %s version: %q
Error message
invalid %s version: %q
What it means
`go mod edit` argument parsing: the argument contained `@version`, but the version fails `allowedVersionArg`. Valid versions are canonical semver (`v1.2.3`), pseudo-versions (`v1.2.3-0.20240101000000-abcdef123456`), or the special tokens `latest`, `upgrade`, `patch`. `adj` indicates which flag produced the argument.
Source
Thrown at src/cmd/go/internal/modcmd/edit.go:385
// describe any errors.
func parsePathVersionOptional(adj, arg string, allowDirPath bool) (path, version string, err error) {
if allowDirPath && modfile.IsDirectoryPath(arg) {
return arg, "", nil
}
before, after, found, err := modload.ParsePathVersion(arg)
if err != nil {
return "", "", err
}
if !found {
path = arg
} else {
path, version = strings.TrimSpace(before), strings.TrimSpace(after)
}
if err := module.CheckImportPath(path); err != nil {
return path, version, fmt.Errorf("invalid %s path: %v", adj, err)
}
if path != arg && !allowedVersionArg(version) {
return path, version, fmt.Errorf("invalid %s version: %q", adj, version)
}
return path, version, nil
}
// parseVersionInterval parses a single version like "v1.2.3" or a closed
// interval like "[v1.2.3,v1.4.5]". Note that a single version has the same
// representation as an interval with equal upper and lower bounds: both
// Low and High are set.
func parseVersionInterval(arg string) (modfile.VersionInterval, error) {
if !strings.HasPrefix(arg, "[") {
if !allowedVersionArg(arg) {
return modfile.VersionInterval{}, fmt.Errorf("invalid version: %q", arg)
}
return modfile.VersionInterval{Low: arg, High: arg}, nil
}
if !strings.HasSuffix(arg, "]") {
return modfile.VersionInterval{}, fmt.Errorf("invalid version interval: %q", arg)
}View on GitHub (pinned to b6b368adc5)
Solutions
- Use a canonical semver tag with the `v` prefix, e.g. `v1.2.3`.
- Use `latest` if you want the newest version resolved by the proxy.
- For non-semver tags, derive the pseudo-version or retag the release with semver.
Example fix
// before go mod edit -require foo@1.0.0 // after go mod edit -require foo@v1.0.0
Defensive patterns
Strategy: validation
Validate before calling
// Validate semver shape with the v prefix.
func validVersion(v string) bool {
if v == "latest" || v == "upgrade" || v == "patch" { return true }
if !strings.HasPrefix(v, "v") { return false }
return semver.IsValid(v) // import "golang.org/x/mod/semver"
} Prevention
- Always include the `v` prefix on semver versions.
- Validate with `semver.IsValid` before scripting `go mod edit`.
- Convert non-semver tags to pseudo-versions or retag with semver.
When it happens
Trigger: `go mod edit -require foo@1.0.0` (missing `v`); `go mod edit -require foo@v1` (incomplete semver); `go mod edit -require foo@randomstring`.
Common situations: Forgetting the `v` prefix; using a git tag that is not semver-shaped; passing a branch name instead of a version.
Related errors
- invalid version: %q
- invalid %s path: %v
- module requires Go ${p.Module.GoVersion} or later
- must have SWIG version >= 3.0.6
- %s (in %s): %w
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/0a08cc00c0670216.
Report an issue: GitHub.