gitbutlerapp/gitbutler · error

Failed to find commit {target} in rebase editor

Error message

Failed to find commit {target} in rebase editor

What it means

`Editor::select_commit` scans the loaded commit graph for a `Pick` step whose commit id equals `target` and returns this error when no step matches. The editor only knows commits that are part of the current rebase graph snapshot; anything else — dropped commits, rewritten/amended ids, commits in other worktrees — is 'not found'. Use `try_select_commit` for an Option-based probe.

Source

Thrown at crates/but-rebase/src/graph_rebase/mutate.rs:241

impl ToSelector for &gix::refs::FullNameRef {
    fn to_selector(&self, editor: &Editor<impl RefMetadata>) -> Result<Selector> {
        editor.select_reference(self)
    }
}

impl ToSelector for gix::refs::FullName {
    fn to_selector(&self, editor: &Editor<impl RefMetadata>) -> Result<Selector> {
        editor.select_reference(self.as_ref())
    }
}

/// Operations for mutating the commit graph
impl<M: RefMetadata> Editor<'_, '_, M> {
    /// Get a selector to a particular commit in the graph
    pub fn select_commit(&self, target: gix::ObjectId) -> Result<Selector> {
        match self.try_select_commit(target) {
            Some(selector) => Ok(selector),
            None => Err(anyhow!("Failed to find commit {target} in rebase editor")),
        }
    }

    /// Get a selector to a particular reference in the graph
    pub fn select_reference(&self, target: &gix::refs::FullNameRef) -> Result<Selector> {
        match self.try_select_reference(target) {
            Some(selector) => Ok(selector),
            None => Err(anyhow!(
                "Failed to find reference {target} in rebase editor"
            )),
        }
    }

    /// Get a selector to a particular commit in the graph
    pub fn try_select_commit(&self, target: gix::ObjectId) -> Option<Selector> {
        for node_idx in self.graph.node_indices() {
            if let Step::Pick(Pick { id, .. }) = self.graph[node_idx]
                && id == target

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Refresh/rebuild the editor (and its graph) right before selecting, and use ids read from that same snapshot
  2. Switch to `try_select_commit(target)` and handle None explicitly when absence is expected
  3. Verify the id exists and participates in the graph first (e.g. `repo.has_object` plus a graph lookup) if you need a better error message
  4. If the id came from serialized state (oplog, UI), re-resolve it through a ref or workspace query instead of trusting the raw OID

Example fix

// before
let sel = editor.select_commit(oid)?; // Err: Failed to find commit ... in rebase editor

// after
use anyhow::Context;
let sel = editor
    .try_select_commit(oid)
    .with_context(|| format!("commit {oid} not in editor graph; refresh workspace and retry with the current id"))?;
Defensive patterns

Strategy: validation

Validate before calling

// Probe without erroring — try_select_commit is the built-in guard:
let Some(sel) = editor.try_select_commit(oid) else {
    anyhow::bail!("commit {oid} not present in editor graph; refresh and retry");
};

Try / catch

match editor.select_commit(oid) {
    Ok(sel) => sel,
    Err(e) if e.to_string().contains("Failed to find commit") => {
        let editor = rebuild_editor()?; // refresh graph snapshot
        editor.select_commit(oid)?
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling `select_commit` with an OID captured before an amend/rebase rewrote it; a commit pruned from the workspace; a commit from a different repository or worktree; a bare OID never added as a Pick step in this editor's graph.

Common situations: Stale object ids held across a workspace refresh in GitButler flows; concurrent modification between reading the graph and selecting; tests using hardcoded OIDs against regenerated fixtures.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/f679da13d5c58171. Report an issue: GitHub.