GitoxideLabs/gitoxide · error
the selected review return commit does not descend from the…
Error message
the selected review return commit does not descend from the reviewed commit
What it means
When an explicit fallback return commit is supplied to `finish_with_progress`, the library requires that commit to descend from the reviewed commit (tip of the review). If `graph.is_ancestor(tip, fallback)` fails, the fallback is not a valid destination to move reviewed work onto and the operation is refused.
Solutions
- Pass a fallback commit that is a descendant of the review tip, e.g. `git merge-base --is-ancestor <tip> <fallback>` first.
- Pass `None` for fallback so the library resolves the stored return reference instead.
- Re-resolve the fallback id from the current branch tip if the branch was rebased.
Example fix
// before
finish_with_progress(repo, &graph, review_id, Some(stale_return_id), progress)?;
// after
let tip = /* peel review ref */;
if !graph.is_ancestor(tip, stale_return_id) {
finish_with_progress(repo, &graph, review_id, None, progress)?;
} else {
finish_with_progress(repo, &graph, review_id, Some(stale_return_id), progress)?;
} Defensive patterns
Strategy: validation
Validate before calling
if let Some(fallback) = fallback_id {
if !graph.is_ancestor(review_tip, fallback) {
return Err(anyhow::anyhow!("fallback return commit must descend from the reviewed commit"));
}
} Prevention
- Derive the fallback id from the current branch tip at call time, never from cached values.
- Prefer passing `None` and letting the library resolve the stored return reference.
- After any rebase, refresh all stored ObjectIds before finishing reviews.
When it happens
Trigger: Calling `finish_with_progress(repo, graph, review, Some(fallback_id), ...)` where `fallback_id` is an unrelated commit, an ancestor of the review tip, or on a divergent branch.
Common situations: The caller cached an old return commit id that was later rebased away; a typo or stale ObjectId from another session was passed; the user picked a return point on a sibling branch.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- HEAD must be the review commit or one of its successors…
- the review return reference no longer descends from the…
- Tried to use as tree, but was
- Tried to use as commit, but was
- Tried to use as tag, but was
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/8cc666c02d25101f.
Report an issue: GitHub.
Appendix: source
Thrown at gix-tix/src/edit/review.rs:260
let base = commit
.parents
.first()
.copied()
.context("a review commit must have a base")?;
let mut reference = repo
.find_reference(review_ref.as_ref())
.context("the review reference is missing")?;
let legacy_reattach = reference.target().try_name().map(ToOwned::to_owned);
let tip = reference
.peel_to_id()
.context("the review reference does not resolve")?
.detach();
let delete_refs = resources(&repo, review_ref.clone())?;
let return_name = return_to(&commit)?.or(legacy_reattach);
let has_return = return_name.is_some();
let checkout = if let Some(id) = fallback {
if !graph.is_ancestor(tip, id) {
anyhow::bail!("the selected review return commit does not descend from the reviewed commit");
}
Some((id, None))
} else {
return_name
.map(|name| {
let Some(mut reference) = repo.try_find_reference(name.as_ref())? else {
return Ok(None);
};
let checkout_reference = if name.as_bstr().starts_with(history::PIN_PREFIX) {
reference.target().try_name().map(ToOwned::to_owned)
} else {
Some(name)
};
let id = reference
.peel_to_id()
.context("the review return reference does not resolve")?
.detach();
if !graph.is_ancestor(tip, id) {View on GitHub (pinned to e73179060b)