GitoxideLabs/gitoxide · error
a non-empty checkout path has a checkout
Error message
a non-empty checkout path has a checkout
What it means
This `expect` panic (gix-tix/src/edit/rebase.rs:1081) unwraps an `Option<Id>` named `checkout` (the currently checked-out commit). The invariant: whenever `checkout_path` is non-empty, a checkout commit must have been determined earlier (the code that populated `checkout_path` always sets the commit). The panic fires if `checkout_path` is non-empty but `checkout` is `None`.
Solutions
- Only set `checkout_path` when a checkout commit was successfully resolved; keep the two values derived from the same source.
- Replace the `expect` with an explicit error: bail with a message that the repository has no resolvable checkout for the given path.
- Resolve the checked-out commit earlier (via `repo.head()`/worktree info) and propagate any failure instead of deferring to the assertion.
Example fix
// before
if !repeat && !checkout_path.is_empty() {
let checkout = checkout.expect("a non-empty checkout path has a checkout");
// after
if !repeat && !checkout_path.is_empty() {
let Some(checkout) = checkout else {
anyhow::bail!("checkout path {:?} is set but no checked-out commit could be resolved", checkout_path);
}; Defensive patterns
Strategy: type-guard
Validate before calling
// Before entering the checkout-dependent branch:
anyhow::ensure!(
checkout_path.is_empty() || checkout.is_some(),
"checkout path is set but no checked-out commit was resolved"
); Type guard
fn resolved_checkout(checkout: Option<gix::Id>, path: &str) -> Option<gix::Id> {
match (path.is_empty(), checkout) {
(false, Some(id)) => Some(id),
_ => None,
}
} Try / catch
// Fail with context instead of panicking:
let Some(checkout) = checkout else {
anyhow::bail!("operation requires a checked-out commit, but none was resolved for {:?}", checkout_path);
}; Prevention
- Derive `checkout_path` and the checkout `Id` from the same resolution step so they cannot diverge.
- Reject the operation early in bare or detached-worktree repositories where no checkout exists.
- Replace expect() with explicit error propagation when the invariant depends on repo state.
When it happens
Trigger: Running the rebase edit path where a checkout worktree path was recorded (`checkout_path` non-empty) but the corresponding `Option<Id>` remained `None` — e.g. a bare repository, a detached-worktree setup, or code path that fills `checkout_path` from config/args without resolving the checked-out commit.
Common situations: Invoking the operation in a bare repository or from a linked worktree where `checkout_exclusive`-style state is absent, or after an API/version change where the field population logic no longer matches the assertion (schema/behavior drift between gix versions for worktree state).
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- is checked out in another worktree
- parser must have set some object value
- successful iteration has outcome
- valid ASCII
- every parent is set only once
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/8f60b00a673ccc91.
Report an issue: GitHub.
Appendix: source
Thrown at gix-tix/src/edit/rebase.rs:1081
..Progress::default()
};
report(None, progress);
let checkout = if repo.workdir().is_some() {
repo.head()?.id().map(gix::Id::detach)
} else {
None
};
let checkout_path: HashSet<_> = checkout
.into_iter()
.flat_map(|checkout| {
affected
.iter()
.copied()
.filter(move |id| graph.is_ancestor(*id, checkout))
})
.collect();
if !repeat && !checkout_path.is_empty() {
let checkout = checkout.expect("a non-empty checkout path has a checkout");
let scan_from = if allow_pending_checkout && root == Some(checkout) {
repo.find_commit(checkout)?
.decode()?
.into_owned()?
.parents
.first()
.copied()
} else {
Some(checkout)
};
if let Some(id) = scan_from {
reject_pending_checkout_path(&repo, id)?;
}
}
validate(&repo, graph, &affected, removed, repeat, tree_mode)?;
let signing = repo
.commit_signing_options_if_enabled()View on GitHub (pinned to e73179060b)