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

  1. Use a canonical semver tag with the `v` prefix, e.g. `v1.2.3`.
  2. Use `latest` if you want the newest version resolved by the proxy.
  3. 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

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


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/0a08cc00c0670216. Report an issue: GitHub.