golang/go · error
ambiguous revision %s
Error message
ambiguous revision %s
What it means
Thrown during git revision resolution (in the Stat method) when a hash prefix supplied as the revision matches two or more distinct full commit hashes in the known refs. The prefix is ambiguous — there is no way to pick one deterministically, so resolution fails immediately rather than guessing.
Source
Thrown at src/cmd/go/internal/modfetch/codehost/git.go:490
} else if refs["refs/heads/"+rev] != "" {
ref = "refs/heads/" + rev
hash = refs[ref]
rev = hash // Replace rev, because meaning of refs/heads/foo can change.
} else if rev == "HEAD" && refs["HEAD"] != "" {
ref = "HEAD"
hash = refs[ref]
rev = hash // Replace rev, because meaning of HEAD can change.
} else if len(rev) >= minHashDigits && len(rev) <= r.hexHashLen() && AllHex(rev) {
// At the least, we have a hash prefix we can look up after the fetch below.
// Maybe we can map it to a full hash using the known refs.
prefix := rev
// Check whether rev is prefix of known ref hash.
for k, h := range refs {
if strings.HasPrefix(h, prefix) {
if hash != "" && hash != h {
// Hash is an ambiguous hash prefix.
// More information will not change that.
return nil, fmt.Errorf("ambiguous revision %s", rev)
}
if ref == "" || ref > k { // Break ties deterministically when multiple refs point at same hash.
ref = k
}
rev = h
hash = h
}
}
if hash == "" && len(rev) == r.hexHashLen() { // Didn't find a ref, but rev is a full hash.
hash = rev
}
} else {
return r.unknownRevisionInfo(refs), &UnknownRevisionError{Rev: rev}
}
defer func() {
if info != nil {
info.Origin.Hash = info.NameView on GitHub (pinned to b6b368adc5)
Solutions
- Use a longer hash prefix (12+ hex chars) to disambiguate: 'go get module@abcdef123456'.
- Use the full 40-char commit hash to eliminate ambiguity.
- Reference a tag or branch name instead of a hash prefix.
- Use a canonical version like v1.2.3 or a full pseudo-version.
Example fix
# before: ambiguous short hash go get example.com/mod@abc123 # after: use the full hash go get example.com/mod@abc123def4567890abcdef1234567890abcdef12
Defensive patterns
Strategy: validation
Validate before calling
// Validate that a hash prefix is long enough to be unambiguous
// before calling Stat
func minHashPrefixLen() int { return 12 }
func validateHashPrefix(rev string) error {
if !codehost.AllHex(rev) { return nil }
if len(rev) >= 4 && len(rev) < minHashPrefixLen() {
return fmt.Errorf("hash prefix %q too short; use at least %d hex chars to avoid ambiguity", rev, minHashPrefixLen())
}
return nil
} Type guard
null
Try / catch
// On 'ambiguous revision', retry with the full hash
info, err := repo.Stat(ctx, shortHash)
if err != nil && strings.Contains(err.Error(), "ambiguous revision") {
// resolve the full hash externally and retry
full, rerr := resolveFullHash(shortHash)
if rerr != nil { return rerr }
return repo.Stat(ctx, full)
} Prevention
- Use 12+ hex character prefixes (the canonical ShortenSHA1 length) for commit references.
- Prefer full 40-char hashes or version tags over short prefixes.
- Document the minimum prefix length for your team's go get usage.
When it happens
Trigger: Calling Stat (via go get module@<short-hash>) where the short hash prefix matches multiple commits across different refs/tags. The loop over refs finds two different full hashes both starting with the prefix.
Common situations: Using a very short hash prefix (e.g. 4-7 chars) in a repo with many commits; a repo where two commits happen to share a long prefix; pseudo-version construction with an insufficiently specific hash.
Related errors
- revision does not exist locally: %s
- no explicit url was passed
- 'git credential fill' failed (url=%s): %w %s
- 'git credential fill' failed for url=%s, could not parse url
- requested a credential for %s, but 'git credential fill' pro
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/32b18d03c25f155e.
Report an issue: GitHub.