{"record":{"id":"cb6b224ff8591d0d","repo":"gitbutlerapp/gitbutler","slug":"cannot-order-selected-commits-by-parentage-selected-commit","errorCode":null,"errorMessage":"Cannot order selected commits by parentage: selected commit {} could not be ranked from editor graph nodes","messagePattern":"Cannot order selected commits by parentage: selected commit (.+?) could not be ranked from editor graph nodes","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-rebase/src/graph_rebase/ordering.rs","lineNumber":57,"sourceCode":"            }\n        }\n\n        if selected.len() <= 1 {\n            return Ok(selected.into_iter().map(|s| s.selector).collect());\n        }\n\n        // Build a deterministic rank from editor step-graph order.\n        let selected_ids = selected\n            .iter()\n            .map(|commit| commit.id)\n            .collect::<HashSet<_>>();\n        let step_graph_rank = step_graph_parent_to_child_rank(self, &selected_ids)?;\n\n        // Preserve the Result contract: unreachable selected commits are a runtime error,\n        // not an internal panic.\n        for commit in &selected {\n            if !step_graph_rank.contains_key(&commit.id) {\n                bail!(\n                    \"Cannot order selected commits by parentage: selected commit {} could not be ranked from editor graph nodes\",\n                    commit.id\n                );\n            }\n        }\n\n        // The rank map is the sole source of truth for deterministic parent-before-child ordering.\n        selected.sort_by_key(|commit| {\n            let rank = step_graph_rank\n                .get(&commit.id)\n                .copied()\n                .unwrap_or(usize::MAX);\n            (rank, commit.input_order)\n        });\n\n        Ok(selected.into_iter().map(|s| s.selector).collect())\n    }\n}","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-rebase/src/graph_rebase/ordering.rs#L39-L75","documentation":"order_commit_selectors_by_parentage ranks selected commits topologically using the editor's step graph. Every selected commit must be rankable from graph nodes; if one is missing from the computed rank map, ordering would silently drop it, so the library bails to preserve the Result contract.","triggerScenarios":"Calling order_commit_selectors_by_parentage (e.g. via prepare_squash_step_for_editor) with a selected commit whose ObjectId has no corresponding rankable node — the commit is not represented in the editor graph (never picked, dropped, or from another history).","commonSituations":"Squash selections containing commits not part of the current rebase; ids captured before history was rewritten; passing raw object ids from the repo instead of ids present as picks in the editor graph.","solutions":["Ensure every selected commit exists as a Pick node in the current editor graph","Rebuild the editor from the current history so the graph includes all selected commits","Filter selected commits down to ids present in the graph before ordering"],"exampleFix":"// before\nlet ordered = editor.order_commit_selectors_by_parentage(&selected)?; // stale id\n// after\nlet selected: Vec<_> = selected.into_iter()\n    .filter(|c| editor.lookup_step(Selector::from(c.id)).is_ok())\n    .collect();\nlet ordered = editor.order_commit_selectors_by_parentage(&selected)?;","handlingStrategy":"validation","validationCode":"let rank = step_graph_parent_to_child_rank(editor, &selected_ids)?;\nif selected.iter().any(|c| !rank.contains_key(&c.id)) { return Err(anyhow!(\"unrankable selection\")); }","typeGuard":"fn all_rankable(selected: &[Commit], rank: &HashMap<StepGraphRank, ()>) -> bool {\n    selected.iter().all(|c| rank.contains_key(&c.id))\n}","tryCatchPattern":null,"preventionTips":["Select only commits present as picks in the current editor graph","Rebuild the editor after history rewrites before ordering","Filter selections against graph node ids"],"tags":["rebase","graph","ordering","lookup"],"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"}