{"record":{"id":"594c70c6881c5fb3","repo":"gitbutlerapp/gitbutler","slug":"failed-to-find-corresponding-parent","errorCode":null,"errorMessage":"Failed to find corresponding parent","messagePattern":"Failed to find corresponding parent","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-rebase/src/graph_rebase/rebase.rs","lineNumber":172,"sourceCode":"                    }\n\n                    output_graph.add_node(Step::Reference { refname, mutable })\n                }\n                Step::None => output_graph.add_node(Step::None),\n            };\n\n            graph_mapping.insert(step_idx, new_idx);\n\n            let mut edges = self\n                .graph\n                .edges_directed(step_idx, petgraph::Direction::Outgoing)\n                .collect::<Vec<_>>();\n            edges.sort_by_key(|e| e.weight().order);\n            edges.reverse();\n\n            for e in edges {\n                let Some(new_parent) = graph_mapping.get(&e.target()) else {\n                    bail!(\"Failed to find corresponding parent\");\n                };\n\n                output_graph.add_edge(new_idx, *new_parent, e.weight().clone());\n            }\n        }\n\n        // Find deleted references. `initial_references` only contains mutable\n        // references, so immutable references are never considered for deletion.\n        for reference in self.initial_references.iter() {\n            if !ref_edits.iter().any(|e| e.name == *reference)\n                && !unchanged_references.iter().any(|e| e == reference)\n            {\n                ref_edits.push(RefEdit::delete(reference.clone(), PreviousValue::MustExist));\n            }\n        }\n\n        history.add_revision(graph_mapping);\n","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-rebase/src/graph_rebase/rebase.rs#L154-L190","documentation":"After rebuilding each node in the output graph, the algorithm re-adds edges to its parents using graph_mapping to translate old parent node indices to new ones. If a parent's target index is missing from graph_mapping, the corresponding output parent does not exist and the edge cannot be rewired, so the rebase aborts. This means a commit was rewritten into the output graph while its parent was not.","triggerScenarios":"Rebase where an edge target node was never mapped into the output graph — e.g. a parent step was skipped, pruned, or the mapping insertion failed for that node.","commonSituations":"Partial rebases dropping commits that are still referenced as parents; internal graph-construction bugs; plans assembled manually with dangling parent references.","solutions":["Ensure every parent commit of each step is included in the rebase plan or its ancestors are fully mapped.","Rebuild the step list so no commit's parent is excluded while the commit itself is kept.","If triggered by a but-rebase bug, report with the failing step sequence."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Every kept commit's parents must also be kept (or be ancestors of base)\nfn parents_covered(steps: &[RebaseStep]) -> bool {\n    let kept: std::collections::HashSet<_> = steps.iter().filter_map(|s| match s {\n        RebaseStep::Pick(p) => Some(p.commit_id), _ => None }).collect();\n    steps.iter().all(|s| match s {\n        RebaseStep::Pick(p) => p.parent_ids.iter().all(|pp| kept.contains(pp)), _ => true })\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Include full parent chains when constructing rebase plans","Drop dependent commits together with their parents","Verify graph connectivity before executing the rebase"],"tags":["rebase","graph","parent"],"backgroundTag":"record-not-found","analyzedSha":"58e5313667b857ef39a730e380af31816a7b1768","analyzedAt":"2026-09-18T06:50:32.052Z","contentChangedAt":"2026-09-18T06:50:32.052Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}