{"record":{"id":"174b40dddf2159d0","repo":"gitbutlerapp/gitbutler","slug":"commit-id-str-does-not-refer-to-a-commit","errorCode":null,"errorMessage":"'{commit_id_str}' does not refer to a commit","messagePattern":"'(.+?)' does not refer to a commit","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but/src/command/legacy/resolve.rs","lineNumber":190,"sourceCode":"        );\n    }\n\n    // Extract the commit OID from the matched CliId\n    match &matches[0] {\n        CliId::Commit {\n            commit: CommitId { commit_id, .. },\n            id: _,\n        } => {\n            let commit_ref = theme::Commit(CommitIdRef {\n                commit_id: *commit_id,\n                change_id: id_map\n                    .change_id_ref(*commit_id)\n                    .map(|change_id| &change_id.change_id),\n            })\n            .to_string();\n            Ok((*commit_id, commit_ref))\n        }\n        _ => bail!(\"'{commit_id_str}' does not refer to a commit\"),\n    }\n}\n\nfn enter_resolution(ctx: &mut Context, out: &mut OutputChannel, commit_id_str: &str) -> Result<()> {\n    let t = theme::get();\n    use gix::{prelude::ObjectIdExt as _, revision::walk::Sorting};\n\n    let (commit_gix_oid, commit_ref) = parse_commit_id(ctx, commit_id_str)?;\n\n    // Get the commit and check if it's conflicted\n    let repo = ctx.repo.get()?;\n    let commit = repo\n        .find_commit(commit_gix_oid)\n        .context(\"Failed to find commit\")?;\n\n    if !commit.is_conflicted() {\n        bail!(\n            \"Commit {commit_ref} is not in a conflicted state. Only conflicted commits can be resolved.\"","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but/src/command/legacy/resolve.rs#L172-L208","documentation":"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).","triggerScenarios":"`but resolve <branch-id>` or `but resolve <uncommitted-file-id>` — IDs that resolve fine in the IdMap but are not commits.","commonSituations":"Confusing a lane ID with a commit ID in `but status` output; muscle memory from branch-accepting commands like `but land`.","solutions":["Pick the commit ID from the commits section of `but status`.","To resolve uncommitted (worktree) conflicts, use `but resolve <path>...` with file paths instead.","To act on a whole lane, use a branch-oriented command — commit resolution is the wrong flow."],"exampleFix":"# before\nbut resolve b2           # b2 is a lane -> 'b2' does not refer to a commit\n\n# after\nbut resolve 4z           # 4z is a commit on that lane\nbut resolve src/lib.rs   # or mark an uncommitted conflict resolved by path","handlingStrategy":"type-guard","validationCode":"# Commit-resolution needs a commit ID; paths go to the mark-resolved form\nbut status   # take IDs from the commits section, not the lanes section","typeGuard":"// Only proceed when the resolved entity is a commit\nmatch &matches[0] {\n    CliId::Commit { commit: CommitId { commit_id, .. }, .. } => { /* safe to enter resolution */ }\n    _ => { /* reject before calling the resolve API */ }\n}","tryCatchPattern":null,"preventionTips":["Check which section of `but status` an ID comes from before passing it to a commit-scoped command.","For uncommitted conflicts use file paths; for whole lanes use branch-oriented commands."],"tags":["cli","resolve","id-resolution","type-mismatch","gitbutler"],"backgroundTag":"wrong-entity-type-for-id","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","schemaVersion":2},"datasetVersion":"2026-08-23T16:17:53.355Z"}