golang/go · warning
ref moved from to
Error message
ref %q moved from %s to %s
What it means
Thrown by gitRepo.CheckReuse when the recorded ref still exists in the remote refs but now points to a different hash than old.Hash — the ref was updated (e.g. branch moved forward, tag was moved). This means the cached checkout may be stale relative to the ref it claims to track.
Solutions
- Update the dependency to the new ref: 'go get module@<ref>'.
- Pin to a specific immutable version tag or commit hash instead of a mutable branch.
- If a moved tag is the issue, coordinate with the upstream maintainer.
- Run 'go mod tidy' after updating to reconcile transitive deps.
Example fix
// before: tracking a branch that moved go get example.com/mod@main // after: pin to a specific tag go get example.com/mod@v1.4.0
Defensive patterns
Strategy: fallback
Validate before calling
null
Type guard
null
Try / catch
// On 'ref moved', re-stat against the new ref
err := repo.CheckReuse(ctx, old, subdir)
if err != nil && strings.Contains(err.Error(), "moved") {
// accept that the ref advanced; re-resolve
info, ferr := repo.Stat(ctx, old.Ref)
if ferr == nil { return useInfo(info) }
return ferr
} Prevention
- Avoid depending on mutable branch refs for reproducible builds.
- Pin to semantic version tags or commit hashes in go.mod.
- Run 'go mod tidy' regularly to catch ref drift early.
When it happens
Trigger: CheckReuse on a module sourced from a mutable ref (branch or moved tag) where the upstream ref now resolves to a different commit. The cached repo was recorded against old.Hash but the remote now has a new hash for old.Ref.
Common situations: Depending on a branch (not a tag) that received new commits; a tag that was force-moved (unusual but possible);a pseudo-version whose underlying ref advanced; using 'latest' or a branch name in go get.
Related errors
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/334bcfd4d5baa6cf.
Report an issue: GitHub.
Appendix: source
Thrown at src/cmd/go/internal/modfetch/codehost/git.go:227
// In that case we assume it does in the absence of any real way to check.
// But if neither Hash nor TagSum is present, we have nothing to check,
// which we take to mean we didn't record enough information to be sure.
if old.Hash == "" && old.TagSum == "" && old.RepoSum == "" {
return fmt.Errorf("non-specific origin")
}
r.loadRefs(ctx)
if r.refsErr != nil {
return r.refsErr
}
if old.Ref != "" {
hash, ok := r.refs[old.Ref]
if !ok {
return fmt.Errorf("ref %q deleted", old.Ref)
}
if hash != old.Hash {
return fmt.Errorf("ref %q moved from %s to %s", old.Ref, old.Hash, hash)
}
}
if old.TagSum != "" {
tags, err := r.Tags(ctx, old.TagPrefix)
if err != nil {
return err
}
if tags.Origin.TagSum != old.TagSum {
return fmt.Errorf("tags changed")
}
}
if old.RepoSum != "" {
if r.repoSum(r.refs) != old.RepoSum {
return fmt.Errorf("refs changed")
}
}
return nil
}View on GitHub (pinned to b6b368adc5)