golang/go · info
refs changed
Error message
refs changed
What it means
Thrown by gitRepo.CheckReuse when old.RepoSum is set and the current repo-wide ref checksum (computed over all refs via repoSum) differs from the recorded value. This is a coarser check than TagSum — it covers the entire ref set, so any ref change (heads or tags) triggers it.
Source
Thrown at src/cmd/go/internal/modfetch/codehost/git.go:241
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
}
// loadRefs loads heads and tags references from the remote into the map r.refs.
// The result is cached in memory.
func (r *gitRepo) loadRefs(ctx context.Context) (map[string]string, error) {
if r.local { // Return results from the cache if local only.
// In the future, we could consider loading r.refs using local git commands
// if desired.
return nil, nil
}
r.refsOnce.Do(func() {
// The git protocol sends all known refs and ls-remote filters them on the client side,
// so we might as well record both heads and tags in one shot.
// Most of the time we only care about tags but sometimes we care about heads too.
release, err := base.AcquireNet()View on GitHub (pinned to b6b368adc5)
Solutions
- Re-fetch the module: 'go mod download module' or 'go get module@<version>'.
- Pin to a specific immutable version to avoid sensitivity to ref churn.
- If the error is persistent and unwanted, verify GOPROXY settings allow re-fetch.
- Clear cache: 'go clean -cache' then retry.
Example fix
# before: stale RepoSum in cache go build ./... # 'refs changed' # after go mod download example.com/mod go build ./...
Defensive patterns
Strategy: fallback
Validate before calling
null
Type guard
null
Try / catch
// 'refs changed' is benign; re-fetch and continue
err := repo.CheckReuse(ctx, old, subdir)
if err != nil && strings.Contains(err.Error(), "refs changed") {
info, ferr := repo.Stat(ctx, rev)
if ferr == nil { return useInfo(info) }
return ferr
} Prevention
- Pin modules to immutable versions to reduce ref-check sensitivity.
- Periodically refresh the cache with 'go mod download'.
- If these errors are noisy, pin to commit hashes for full determinism.
When it happens
Trigger: CheckReuse where any ref in the upstream repo changed since the cache entry was written: new commits on any branch, new tags, deleted branches. RepoSum hashes the full refs map from ls-remote.
Common situations: Upstream repo received new commits or tags since last cache; depending on a module via a branch or HEAD; the module is under active development. Like 'tags changed' but broader scope.
Related errors
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/ab0a187e22d03c19.
Report an issue: GitHub.