gitbutlerapp/gitbutler · error

Could not find commit

Error message

Could not find commit {commit_id}

What it means

This is the fallback branch of the same commit lookup: when the iterator over indexed stack commits yields no match for the requested `commit_id`, the resolver reports that the commit cannot be found in the current workspace state.

Solutions

  1. Run `but status` (or the log TUI) to list currently managed commit ids and use one of those.
  2. If the commit should be managed, apply/assign its branch to the workspace so it is indexed, then retry.
  3. Verify the id is correct (copy the full or abbreviated hash from the intended commit) and refresh workspace state before retrying.
Defensive patterns

Strategy: try-catch

Validate before calling

// before resolving, confirm the id is among managed commits
if !managed_commit_ids().contains(&commit_id) {
    eprintln!("{} is not managed by the workspace", commit_id);
}

Try / catch

match workspace.find_commit(commit_id) {
    Err(e) if e.to_string().contains("Could not find commit") => {
        eprintln!("Run `but status` for managed ids; apply the branch if needed");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Resolving a commit id that exists in the repository's object database but not in any indexed stack — e.g., referencing an already-pushed-and-removed commit, a commit on an unassigned branch, a typo'd/short id, or querying before the workspace index was refreshed.

Common situations: Using a commit id from `git log` that GitButler no longer manages; referring to a commit whose branch was unapplied; stale CLI state after another process changed the workspace; abbreviated hash that doesn't correspond to a managed commit.

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/f8fcc37c19bb8e60. Report an issue: GitHub.

Appendix: source

Thrown at crates/but/src/id/mod.rs:1804

    pub fn stacks(&self) -> &Vec<StackWithId> {
        self.indexed_stacks.borrow_owner()
    }

    /// Get a distinct commit by ID.
    ///
    /// Errors if the commit cannot be found or if there are multiple matches.
    pub fn get_commit_by_id(&self, commit_id: gix::ObjectId) -> anyhow::Result<CommitWithId<'_>> {
        let mut matches = self
            .commits()
            .filter(|commit_with_id| match commit_with_id {
                CommitWithId::Local(commit) => commit.commit_id() == commit_id,
                CommitWithId::Remote(commit) => commit.commit_id() == commit_id,
            });

        match (matches.next(), matches.next()) {
            (Some(commit), None) => Ok(commit),
            (Some(_), Some(_)) => Err(anyhow::anyhow!("Found multiple matches for {commit_id}")),
            _ => Err(anyhow::anyhow!("Could not find commit {commit_id}")),
        }
    }

    fn commits(&self) -> impl Iterator<Item = CommitWithId<'_>> {
        let stack_commits = self.indexed_stacks.borrow_owner().iter().flat_map(|stack| {
            stack.segments.iter().flat_map(|segment| {
                segment
                    .workspace_commits
                    .iter()
                    .map(CommitWithId::Local)
                    .chain(segment.remote_commits.iter().map(CommitWithId::Remote))
            })
        });

        stack_commits.chain(
            // Commits owned by a linked worktree resolve exactly like workspace commits - they
            // just live outside the stacks.
            self.worktrees

View on GitHub (pinned to 58e5313667)