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

  1. Inspect the review refs manually (e.g. `git for-each-ref` under the review prefix) to find the unreadable ref.
  2. Fix repository storage: repair or delete the corrupt ref file / rebuild packed-refs.
  3. Check filesystem permissions and disk health for the git directory.
  4. 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

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


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)