GitoxideLabs/gitoxide · error
could not read review reference
Error message
could not read review reference: {err} What it means
While iterating review references (refs under the review prefix), one reference could not be read from storage. Missing refs are silently skipped via `is_missing_ref`, but any other read failure aborts the `review_blocks_undo` check with this wrapped error. It means the ref storage itself is unhealthy, not that a ref is absent.
Solutions
- Inspect the review refs manually (e.g. `git for-each-ref` under the review prefix) to find the unreadable ref.
- Fix repository storage: repair or delete the corrupt ref file / rebuild packed-refs.
- Check filesystem permissions and disk health for the git directory.
- If the ref is genuinely gone, ensure the error truly maps to a missing ref so it would be skipped.
Example fix
// before: abort on any ref read error
Err(err) => return Err(anyhow::anyhow!("could not read review reference: {err}")),
// after: keep the missing-ref skip and repair the repository before retrying
Err(err) if crate::history::is_missing_ref(&*err) => continue,
Err(err) => return Err(anyhow::anyhow!("could not read review reference: {err}")), Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check repository ref storage health
repo.references()?.prefixed(crate::history::REVIEW_PREFIX.as_bstr())
.map(|r| r.map(|_| ()))
.collect::<Result<Vec<_>, _>>()?; Try / catch
match repo.undo_check() {
Ok(v) => v,
Err(e) if e.to_string().contains("could not read review reference") => repair_refs_then_retry(),
Err(e) => return Err(e),
} Prevention
- Run `git fsck` periodically on repositories using the undo queue.
- Avoid editing files under .git/refs by hand.
- Check disk/filesystem health on the machine hosting the repo.
When it happens
Trigger: Calling `record`, `position`, `plan_undo`, `plan_redo` (via `review_blocks_undo`) when a ref exists under the review prefix but reference iteration yields an `Err` other than a missing-ref (e.g. corrupt packed-refs entry, I/O error reading the ref file).
Common situations: Corrupted `.git/refs` or `packed-refs` entries; filesystem permission or I/O problems; partially written refs after a crash; worktree with unreadable git dir.
Understand the failure class
Background: "git command failed": what it means when a tool shells out to git and git exits non-zero — this error's family across 21 libraries.
Related errors
- could not inspect a reference before editing
- 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 read reference
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/ff09cf007979438a.
Report an issue: GitHub.
Appendix: source
Thrown at gix-tix/src/edit/undo.rs:164
return Ok(true);
}
let Some(parent) = stored.parent else {
return Ok(false);
};
id = parent;
}
}
pub(crate) fn review_blocks_undo(repo: &gix::Repository) -> Result<bool> {
let references = repo.references().context("could not open review references")?;
for reference in references
.prefixed(crate::history::REVIEW_PREFIX.as_bstr())
.context("could not iterate review references")?
{
let reference = match reference {
Ok(reference) => reference,
Err(err) if crate::history::is_missing_ref(&*err) => continue,
Err(err) => return Err(anyhow::anyhow!("could not read review reference: {err}")),
};
if crate::history::review_number(reference.name().as_bstr()).is_some() {
return Ok(true);
}
}
Ok(false)
}
pub(crate) fn clear(repo: &gix::Repository) -> Result<()> {
let mut edits = Vec::new();
for name in [TIP_REF, CURSOR_REF] {
let Some(reference) = repo
.try_find_reference(name)
.with_context(|| format!("could not read {name}"))?
else {
continue;
};
edits.push(RefEdit::delete(View on GitHub (pinned to e73179060b)