gitbutlerapp/gitbutler · error

'{commit_id_str}' does not refer to a commit

Error message

'{commit_id_str}' does not refer to a commit

What it means

The ID resolved uniquely but to a non-commit entity — a branch/lane or an uncommitted file. The commit-resolution flow (`parse_commit_id` feeding `enter_resolution`) requires a `CliId::Commit`, so it bails with 'does not refer to a commit' (resolve.rs:190).

Source

Thrown at crates/but/src/command/legacy/resolve.rs:190

        );
    }

    // Extract the commit OID from the matched CliId
    match &matches[0] {
        CliId::Commit {
            commit: CommitId { commit_id, .. },
            id: _,
        } => {
            let commit_ref = theme::Commit(CommitIdRef {
                commit_id: *commit_id,
                change_id: id_map
                    .change_id_ref(*commit_id)
                    .map(|change_id| &change_id.change_id),
            })
            .to_string();
            Ok((*commit_id, commit_ref))
        }
        _ => bail!("'{commit_id_str}' does not refer to a commit"),
    }
}

fn enter_resolution(ctx: &mut Context, out: &mut OutputChannel, commit_id_str: &str) -> Result<()> {
    let t = theme::get();
    use gix::{prelude::ObjectIdExt as _, revision::walk::Sorting};

    let (commit_gix_oid, commit_ref) = parse_commit_id(ctx, commit_id_str)?;

    // Get the commit and check if it's conflicted
    let repo = ctx.repo.get()?;
    let commit = repo
        .find_commit(commit_gix_oid)
        .context("Failed to find commit")?;

    if !commit.is_conflicted() {
        bail!(
            "Commit {commit_ref} is not in a conflicted state. Only conflicted commits can be resolved."

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Pick the commit ID from the commits section of `but status`.
  2. To resolve uncommitted (worktree) conflicts, use `but resolve <path>...` with file paths instead.
  3. To act on a whole lane, use a branch-oriented command — commit resolution is the wrong flow.

Example fix

# before
but resolve b2           # b2 is a lane -> 'b2' does not refer to a commit

# after
but resolve 4z           # 4z is a commit on that lane
but resolve src/lib.rs   # or mark an uncommitted conflict resolved by path
Defensive patterns

Strategy: type-guard

Validate before calling

# Commit-resolution needs a commit ID; paths go to the mark-resolved form
but status   # take IDs from the commits section, not the lanes section

Type guard

// Only proceed when the resolved entity is a commit
match &matches[0] {
    CliId::Commit { commit: CommitId { commit_id, .. }, .. } => { /* safe to enter resolution */ }
    _ => { /* reject before calling the resolve API */ }
}

Prevention

When it happens

Trigger: `but resolve <branch-id>` or `but resolve <uncommitted-file-id>` — IDs that resolve fine in the IdMap but are not commits.

Common situations: Confusing a lane ID with a commit ID in `but status` output; muscle memory from branch-accepting commands like `but land`.

Related errors


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