gitbutlerapp/gitbutler · error
Failed to find commit
Error message
Failed to find commit {commit_id} in rebase editor What it means
When planning tree changes for a merge commit, every selected commit id must have first-parent metadata recorded by the rebase editor traversal. If a selected commit id is absent from that map, the traversal never saw it, so its changes cannot be attributed; the library bails rather than silently dropping the commit's changes.
Solutions
- Verify each selected commit id belongs to the merge's first-parent history in the current editor traversal
- Re-create the traversal/editor so first_parent_metadata_by_selected_commit_id is rebuilt from the current history
- Remove stale or foreign commit ids from selected_commit_ids
Example fix
// before let selected = vec![old_commit_id]; // not in current traversal merge_commit_changes_to_tree(editor, &selected)?; // after let selected: Vec<_> = current_traversal.selected_commit_ids().collect(); merge_commit_changes_to_tree(editor, &selected)?;
Defensive patterns
Strategy: validation
Validate before calling
let known: HashSet<_> = traversal.first_parent_metadata_by_selected_commit_id.keys().copied().collect(); assert!(selected.iter().all(|c| known.contains(&c.into())), "selected commit not in traversal");
Type guard
fn all_selected_known(selected: &[gix::ObjectId], meta: &HashMap<gix::ObjectId, FirstParentMetadata>) -> bool {
selected.iter().all(|id| meta.contains_key(id))
} Prevention
- Always derive selected commit ids from the same traversal that feeds the merge planner
- Never reuse ids from previous rebase sessions
- Validate ids against the current history before planning
When it happens
Trigger: Calling merge_commit_changes_to_tree (which calls plan_commit_changes_for_merge) with a selected_commit_ids entry that is not a first-parent commit known to the editor's traversal — e.g. a commit outside the merge's first-parent history, a stale ObjectId, or an id from a different graph.
Common situations: Passing commit ids captured from a previous rebase session after the history was rewritten; selecting commits from a side branch that aren't on the merge's first-parent chain; id mismatch after re-creating the editor.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- An octopus merge commits must have at least two parents
- Base commit must exist if provided
- Branch not found
- cannot currently handle more than 1 parent
- Cannot merge : it shares no history with /
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/2c16dc693160af00.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but-rebase/src/graph_rebase/merge_commit_changes.rs:141
subject_commit_ids: Vec<gix::ObjectId>,
) -> Result<Vec<PlannedCommitChange>> {
self.try_select_commit(target_commit_id).with_context(|| {
format!("Failed to find commit {target_commit_id} in rebase editor")
})?;
let selected_commit_ids = deduplicate_commit_ids(subject_commit_ids);
if selected_commit_ids.is_empty() {
return Ok(Vec::new());
}
let selected_commit_set = selected_commit_ids.iter().copied().collect::<HashSet<_>>();
let traversal = traverse_graph_for_planning(self, target_commit_id, &selected_commit_set)?;
for commit_id in &selected_commit_ids {
if !traversal
.first_parent_metadata_by_selected_commit_id
.contains_key(commit_id)
{
bail!("Failed to find commit {commit_id} in rebase editor");
}
}
// A map from selected commit ID to how many child commits it has that
// are also selected.
let mut selected_child_count = HashMap::<gix::ObjectId, usize>::with_capacity(
traversal.ordered_selected_commit_ids.len(),
);
for commit_id in traversal.ordered_selected_commit_ids.iter().copied() {
selected_child_count.insert(commit_id, 0);
}
for selected_parent_id in traversal
.first_parent_metadata_by_selected_commit_id
.values()
.filter_map(|metadata| metadata.selected_first_parent_id)
{
if let Some(child_count) = selected_child_count.get_mut(&selected_parent_id) {
*child_count += 1;View on GitHub (pinned to 58e5313667)