GitoxideLabs/gitoxide · error · anyhow::Error
could not read reference
Error message
could not read reference: {err} What it means
`loaded_graph` iterates all references to build a history graph; each individual reference read may fail (e.g. the ref points to a missing or non-commit object, or the ref file is corrupt). Such per-reference errors are wrapped as "could not read reference: {err}". Note a missing HEAD short-circuits to an empty graph and does not trigger this.
Solutions
- Identify the broken ref from the inner error and delete or repair it (git update-ref -d)
- Run `git fsck` to find dangling/corrupt references
- Re-pack refs (git pack-refs --all) to rebuild packed-refs
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-flight: verify all refs resolve to existing objects
for r in repo.references()?.all()? {
let r = r.map_err(|e| e)?; // surface broken refs before graph building
let _ = r.try_id()?;
} Try / catch
match loaded_graph(&repo) {
Ok(g) => g,
Err(e) if e.to_string().starts_with("could not read reference") => {
eprintln!("run git fsck and repair broken refs");
HistoryGraph::default()
}
Err(e) => return Err(e),
} Prevention
- Run `git fsck` periodically on long-lived repos
- Avoid `git gc --prune=now` with stale refs present
- Delete dangling refs after force-push cleanup
When it happens
Trigger: Calling edit_graph_ignores_refs_that_do_not_point_to_commits / loaded_graph when `repo.references()?.all()?` yields an Err for some reference — dangling ref to a pruned object, corrupt packed-refs entry, or reflog/oid decode failure.
Common situations: Repos with stale refs after force-pushes and gc; refs pointing to objects deleted by aggressive pruning; corruption from interrupted operations.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- At least one object couldn't be looked up even though it…
- tix stash reference does not use a canonical full commit ID
- rewritten commit already has saved worktree state
- already has saved worktree state
- could not inspect a stash reference before rebasing
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/889faa496718326f.
Report an issue: GitHub.
Appendix: source
Thrown at gix-tix/src/edit/mod.rs:11
use std::{io::Write, process::Command};
use anyhow::{Context, Result};
pub(super) fn loaded_graph(repo: &gix::Repository) -> Result<crate::history::HistoryGraph> {
if repo.head_id().is_err() {
return Ok(crate::history::HistoryGraph::default());
}
let mut revisions = Vec::new();
for reference in repo.references()?.all()? {
let reference = reference.map_err(|err| anyhow::anyhow!("could not read reference: {err}"))?;
if reference.name().as_bstr().starts_with(crate::history::STASH_PREFIX)
|| reference
.name()
.as_bstr()
.starts_with(crate::history::REVIEW_STASH_PREFIX)
|| undo::is_queue_ref(reference.name().as_bstr())
{
continue;
}
let Some(id) = reference.try_id() else { continue };
if reference.name().as_bstr() == b"HEAD"
|| repo
.find_header(id)
.context("could not inspect reference target")?
.kind()
!= gix::object::Kind::Commit
{
continue;View on GitHub (pinned to e73179060b)