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

  1. Verify each selected commit id belongs to the merge's first-parent history in the current editor traversal
  2. Re-create the traversal/editor so first_parent_metadata_by_selected_commit_id is rebuilt from the current history
  3. 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

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


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)