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
- Write the bound as a full semver including patch: '<=v1.2.0' (which is unambiguous and excludes v1.2.3).
- Or use '<v1.3.0' if the intent is 'everything in the 1.2 line'.
- 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
- Write '<=v1.2.0' (full semver) — never '<=v1.2'.
- Reject prefix-style bounds in tooling that builds queries.
- Document the v1.2-vs-v1.2.3 ambiguity for contributors writing version ranges.
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
- invalid previous version %v@%v
- invalid semantic version %q in range %q
- internal error: main module version is not allowed: %w
- can't query specific version (%q) of standard-library module
- internal error: package %s is in the main module (%s), but v
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/eba1e27dfbc6161c.
Report an issue: GitHub.