golang/go · error

ambiguous semantic version %q in range %q

Error message

ambiguous semantic version %q in range %q

What it means

Returned by newQueryMatcher for a '<=' query whose bound is a version prefix (e.g. v1.2) rather than a full canonical version. Because '@v1.2' may resolve to v1.2.3, the toolchain cannot decide unambiguously whether '<=v1.2' should include v1.2.3, so it rejects the query rather than guess.

Source

Thrown at src/cmd/go/internal/modload/query.go:478

		if current == "" || current == "none" {
			return nil, &NoPatchBaseError{path}
		}
		if current == "" {
			qm.mayUseLatest = true
		} else {
			qm.mayUseLatest = module.IsPseudoVersion(current)
			qm.prefix = gover.ModMajorMinor(qm.path, current) + "."
			qm.filter = func(mv string) bool { return gover.ModCompare(qm.path, mv, current) >= 0 }
		}

	case strings.HasPrefix(query, "<="):
		v := query[len("<="):]
		if !gover.ModIsValid(path, v) {
			return badVersion(v)
		}
		if gover.ModIsPrefix(path, v) {
			// Refuse to say whether <=v1.2 allows v1.2.3 (remember, @v1.2 might mean v1.2.3).
			return nil, fmt.Errorf("ambiguous semantic version %q in range %q", v, query)
		}
		qm.filter = func(mv string) bool { return gover.ModCompare(qm.path, mv, v) <= 0 }
		if !matchesMajor(v) {
			qm.preferIncompatible = true
		}

	case strings.HasPrefix(query, "<"):
		v := query[len("<"):]
		if !gover.ModIsValid(path, v) {
			return badVersion(v)
		}
		qm.filter = func(mv string) bool { return gover.ModCompare(qm.path, mv, v) < 0 }
		if !matchesMajor(v) {
			qm.preferIncompatible = true
		}

	case strings.HasPrefix(query, ">="):
		v := query[len(">="):]

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Write the bound as a full semver including patch: '<=v1.2.0' (which is unambiguous and excludes v1.2.3).
  2. Or use '<v1.3.0' if the intent is 'everything in the 1.2 line'.
  3. Validate with gover.ModIsPrefix — if true for your bound, expand it to canonical form before querying.

Example fix

// before
$ go get example.com/pkg@<=v1.2
// error: ambiguous semantic version "v1.2" in range "<=v1.2"

// after
$ go get example.com/pkg@<=v1.2.0   // explicit, excludes v1.2.3
Defensive patterns

Strategy: validation

Validate before calling

// Expand prefix bounds to canonical form for '<=' queries:
//   if gover.ModIsPrefix(path, v) { v = strings.TrimSuffix(v, ".") + ".0"; /* but prefer full version */ }
// Better: require full versions: if gover.ModIsPrefix(path, v) { return ErrAmbiguous }

Type guard

func isUnambiguousLeBound(path, v string) bool {
    return gover.ModIsValid(path, v) && !gover.ModIsPrefix(path, v)
}

Prevention

When it happens

Trigger: Running 'go get example.com/pkg@<=v1.2' or '@<=v2' where the bound omits the patch (and minor) component.

Common situations: Scripts building range queries from truncated version strings; users assuming v1.2 means exactly v1.2.0; CI matrices querying allowed version ceilings with shorthand versions.

Related errors


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