{"record":{"id":"84875534bb011b2c","repo":"gitbutlerapp/gitbutler","slug":"path-cannot-be-resolved-this-way-resolve-this-commit-in-edit","errorCode":null,"errorMessage":"\"{path}\" cannot be resolved this way: {} Resolve this commit in edit mode instead.","messagePattern":"\"(.+?)\" cannot be resolved this way: (.+?) Resolve this commit in edit mode instead\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but/src/command/legacy/resolve.rs","lineNumber":947,"sourceCode":"\n    // Expand a bare path into explicit per-hunk specs; an explicit `:<N>`\n    // target needs no lookup, the API validates it.\n    let hunks: Vec<usize> = match (hunk, &resolution) {\n        (Some(hunk), _) => vec![hunk],\n        (None, _) => {\n            let conflicts = but_api::resolve::commit_conflicts(ctx, commit_oid)?;\n            if conflicts.files.is_empty() && conflicts.manual.is_empty() {\n                bail!(\"Commit {commit_oid} is not conflicted.\");\n            }\n            // Match with the same normalization the API applies, so spellings\n            // it would accept (`./`, backslashes, duplicate slashes) resolve.\n            let lookup = but_api::resolve::normalize_path(path);\n            if let Some(manual) = conflicts\n                .manual\n                .iter()\n                .find(|file| but_api::resolve::normalize_path(&file.path) == lookup)\n            {\n                bail!(\n                    \"\\\"{path}\\\" cannot be resolved this way: {} Resolve this commit in edit mode instead.\",\n                    manual.reason\n                );\n            }\n            let total_hunks = conflicts\n                .files\n                .iter()\n                .find(|conflicted| but_api::resolve::normalize_path(&conflicted.path) == lookup)\n                .map(|conflicted| conflicted.hunks.len())\n                .with_context(|| format!(\"\\\"{path}\\\" is not a conflicted file of this commit\"))?;\n            match &resolution {\n                HunkResolution::Ours | HunkResolution::Theirs | HunkResolution::Ai => {\n                    (1..=total_hunks).collect()\n                }\n                HunkResolution::Content(_) if total_hunks == 1 => vec![1],\n                HunkResolution::Content(_) => bail!(\n                    \"\\\"{path}\\\" has {total_hunks} conflicts; content applies to one at a time, use \\\"{path}:<N>\\\".\"\n                ),","sourceCodeStart":929,"sourceCodeEnd":965,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but/src/command/legacy/resolve.rs#L929-L965","documentation":"In `but resolve`, when the user supplies a resolution for a conflicted file, the command checks whether that path is a 'manual' conflict — one whose reason (e.g. file-level rename/delete/modify conflicts) cannot be fixed by applying hunk content or ours/theirs choices from the CLI. If the path matches a manual conflict entry, it bails telling the user to open edit mode instead.","triggerScenarios":"Running `but resolve <commit> <path>:ours|theirs|:<content>` (apply_resolutions, invoked from handle) where the given path normalizes to a file listed in conflicts.manual rather than conflicts.files.","commonSituations":"Resolving a rename/rename, delete/modify, or other non-hunk conflict from the CLI; typos are not the cause here — the file is conflicted, but its conflict type requires interactive edit mode.","solutions":["Read the printed reason to see why the file cannot be auto-resolved","Run `but` (edit mode) and resolve that commit's conflict interactively","Or run `but resolve cancel`/`but resolve finish` once resolved in edit mode"],"exampleFix":"// before\nbut resolve <commit-id> \"src/lib.rs\":ours\n// error: \"src/lib.rs\" cannot be resolved this way: rename/rename conflict...\n// after\nbut  # open edit mode and resolve the commit interactively","handlingStrategy":"validation","validationCode":"// before applying a resolution, check the path is not a manual conflict\nconst file = conflicts.manual.find(f => normalizePath(f.path) === lookupPath);\nif (file) throw new Error(`Resolve \"${file.path}\" in edit mode: ${file.reason}`);","typeGuard":"const isAutoResolvable = (path, conflicts) =>\n  !conflicts.manual.some(f => normalize(f.path) === normalize(path)) &&\n  conflicts.files.some(f => normalize(f.path) === normalize(path));","tryCatchPattern":null,"preventionTips":["Inspect `but resolve` status output for manual conflicts before scripting resolutions","Route rename/delete-type conflicts to edit mode in automation","Normalize paths consistently when matching conflict entries"],"tags":["cli","conflict-resolution","git"],"backgroundTag":"unsupported-operation","analyzedSha":"58e5313667b857ef39a730e380af31816a7b1768","analyzedAt":"2026-09-18T06:50:32.052Z","contentChangedAt":"2026-09-18T06:50:32.052Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}