GitoxideLabs/gitoxide · error · anyhow::Error

a checked-out review root cannot suspend while returning…

Error message

a checked-out review root cannot suspend while returning from review

What it means

In gix-tix's `edit/forget.rs` (perform_conflict), when a rebase ends in Conflict while a `review_return` is pending (the tool is mid-way returning from a review checkout), the tool cannot suspend the operation — suspending would lose the return state. It refuses with this ensure! error to protect the review workflow invariant.

Solutions

  1. Finish or abort the in-progress review return before re-running the operation
  2. Resolve the underlying rebase conflict so the rebase completes instead of suspending
  3. Reset the review state (checkout the intended branch) and retry
Defensive patterns

Strategy: validation

Validate before calling

// refuse to run while a review return is pending
if review_return.is_some() {
    anyhow::bail!("finish or abort the in-progress review return first");
}

Try / catch

if let Err(e) = perform(...) {
    if e.to_string().contains("cannot suspend while returning from review") {
        // surface guidance to reset review state
    }
}

Prevention

When it happens

Trigger: Invoking the forget/edit operation while a review root is checked out AND the operation is in its return-from-review phase, and the underlying rebase reports a conflict.

Common situations: Users running tix edit/forget commands on top of an in-progress review return; concurrent review sessions; unresolved conflicts left from a previous review step.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08). Data as JSON: /api/errors/879c3257682b9c19. Report an issue: GitHub.

Appendix: source

Thrown at gix-tix/src/edit/forget.rs:99

    } else {
        rebase::perform_deleting_refs_with_progress(
            &repo,
            graph,
            rebase::Edit::Remove { target: id },
            rebase::Signature::RedoIfNeeded,
            rebase::Tree::LeaveAsIsAndMark,
            deletions,
            report,
        )
    }?;
    Ok(match result {
        rebase::Perform::Complete(outcome) => Perform::Complete(Outcome {
            selected: outcome.selected,
            review_return,
            ref_changes: outcome.ref_changes,
        }),
        rebase::Perform::Conflict(rebase) => {
            anyhow::ensure!(
                review_return.is_none(),
                "a checked-out review root cannot suspend while returning from review"
            );
            Perform::Conflict(Conflict { rebase })
        }
    })
}

pub(super) fn preflight_tree_transition(
    repo: &gix::Repository,
    workdir: &Path,
    old: ObjectId,
    new: ObjectId,
) -> Result<()> {
    let mut index = gix::tempfile::writable_at(
        std::env::temp_dir().join(format!(
            "tix-forget-index-{}-{old}-{:?}",
            std::process::id(),

View on GitHub (pinned to e73179060b)