gitbutlerapp/gitbutler · error
A parent in the output graph is not a pick
Error message
A parent in the output graph is not a pick
What it means
During graph-based rebase output reconstruction, a step's parent index was remapped into the output graph, but the node at the new index is not a Pick step (e.g. a Reference or marker node). The rebase machinery requires every parent of a cherry-picked commit in the output graph to be an actual picked commit carrying a commit id. This indicates the output graph structure diverged from the invariants the rebase algorithm maintains.
Solutions
- Inspect the rebase steps: ensure reference steps are ordered so they never become the parent of a pick in the output graph.
- Verify the graph_mapping/output_graph construction for recent changes to but-rebase; this is an invariant violation, likely an internal bug — report with the failing step list.
- Reconstruct the rebase plan without reference steps in parent positions and retry.
Defensive patterns
Strategy: validation
Validate before calling
fn all_parents_are_picks(steps: &[RebaseStep]) -> bool {
// references must never precede a pick that depends on them as a parent
!steps.iter().zip(steps.iter().skip(1)).any(|(prev, next)| {
matches!(prev, RebaseStep::Reference(_)) && matches!(next, RebaseStep::Pick(_))
})
} Prevention
- Keep reference steps ordered after the picks they annotate
- Validate rebase plans before running them
- Treat this as a bug report signal: capture the full step list when it fires
When it happens
Trigger: Calling the rebase operation when graph_mapping maps a step's parent to an output-graph node that is a non-Pick Step variant — typically a Reference step or internal marker node becoming the parent of a pick.
Common situations: Rebases involving virtual branch reference steps interleaved with picks; bugs or regressions in graph construction when references are re-parented; corrupted or hand-edited branch graphs.
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
- A matching parent can't be found in the output graph
- An edge with desired order
- Cannot order selected commits by parentage: selected commit
- Failed to find corresponding parent
- Invalid parent delimitation: requested child is not a…
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/40c5d89558fec095.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but-rebase/src/graph_rebase/rebase.rs:53
// Immutable picks are copied verbatim: the commit keeps its
// id, so there's no cherry-pick to run and nothing to record
// in the history mapping.
output_graph.add_node(Step::Pick(pick))
}
Step::Pick(pick) => {
let graph_parents = collect_ordered_parents(&self.graph, step_idx);
let ontos = match pick.preserved_parents.clone() {
Some(ontos) => ontos,
None => graph_parents
.iter()
.map(|idx| {
let Some(new_idx) = graph_mapping.get(idx) else {
bail!("A matching parent can't be found in the output graph");
};
match output_graph[*new_idx] {
Step::Pick(Pick { id, .. }) => Ok(id),
_ => bail!("A parent in the output graph is not a pick"),
}
})
.collect::<Result<Vec<_>>>()?,
};
let outcome = cherry_pick(
&self.repo,
pick.id,
&ontos,
pick.pick_mode,
pick.tree_merge_mode,
pick.sign_commit,
)?;
if matches!(outcome, CherryPickOutcome::ConflictedCommit(_))
&& !pick.conflictable
{
bail!(View on GitHub (pinned to 58e5313667)