{"record":{"id":"b1c4fe89f7da19b8","repo":"gitbutlerapp/gitbutler","slug":"cannot-amend-into-target-id-the-commit-is-immutable-not-part","errorCode":null,"errorMessage":"cannot amend into {target_id}: the commit is immutable (not part of a mutable branch)","messagePattern":"cannot amend into (.+?): the commit is immutable \\(not part of a mutable branch\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-workspace/src/commit/commit_amend.rs","lineNumber":76,"sourceCode":"    changes: Vec<DiffSpec>,\n    context_lines: u32,\n    source: ChangeSource<'_>,\n) -> Result<CommitAmendOutcome<'ws, 'meta, M>> {\n    let (target_selector, target) = editor.find_selectable_commit(commit)?;\n\n    let target_id = target.id;\n    if target.attach(editor.repo()).is_conflicted() {\n        bail!(\"Cannot amend a conflicted commit\")\n    }\n    // An immutable pick would be replaced in the step graph while the rebase copies\n    // its descendants verbatim and never moves the (immutable) refs pointing at it -\n    // the amended commit would be written but stay unreachable, with this function\n    // still reporting success. Fail fast instead.\n    let Step::Pick(target_pick) = editor.lookup_step(target_selector)? else {\n        bail!(\"BUG: Expected pick step from commit selector. This should never happen\");\n    };\n    if !target_pick.mutable {\n        bail!(\n            \"cannot amend into {target_id}: the commit is immutable (not part of a mutable branch)\"\n        );\n    }\n\n    // Clone before `create_commit` consumes the vec — needed afterwards\n    // to determine which changes were consumed (not rejected).\n    let all_changes = changes.clone();\n    let create_out = create_commit(\n        source.repo(&editor),\n        Destination::AmendCommit {\n            commit_id: target_id,\n            new_message: None,\n        },\n        changes,\n        context_lines,\n    )?;\n\n    let Some(new_commit_id) = create_out.new_commit else {","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-workspace/src/commit/commit_amend.rs#L58-L94","documentation":"Amending is only allowed into commits on a mutable branch. If the target commit is an immutable pick (e.g. part of reviewed/landed history that GitButler treats as read-only), amending it would create an unreachable commit, so the library refuses with this error.","triggerScenarios":"Calling commit_amend with a commit selector whose Step::Pick has mutable == false — i.e. the commit lives on an immutable base branch rather than a mutable workspace branch.","commonSituations":"Trying to amend a commit that has already been pushed/landed to an integrated base branch; scripts that blindly take the first commit in a list which happens to be an upstream commit.","solutions":["Target a commit on a mutable branch instead","If the commit should be mutable, move/assign it into the workspace (mutable) branch first","If the change is needed on top of immutable history, create a new commit rather than amending"],"exampleFix":"// before\neditor.commit_amend(landed_commit_id, msg, source)?; // immutable\n// after\nlet (sel, _) = editor.find_selectable_commit(landed_commit_id)?;\n// pick a workspace commit instead of landed_commit_id\neditor.commit_amend(workspace_commit_id, msg, source)?;","handlingStrategy":"validation","validationCode":"fn is_mutable(editor: &WorkspaceEditor, commit: impl Into<CommitSelector>) -> anyhow::Result<bool> {\n    let (sel, _) = editor.find_selectable_commit(commit)?;\n    Ok(matches!(editor.lookup_step(sel)?, Step::Pick(p) if p.mutable))\n}","typeGuard":"fn is_mutable_pick(step: &Step) -> bool { matches!(step, Step::Pick(p) if p.mutable) }","tryCatchPattern":"match editor.commit_amend(target, msg, source) {\n    Err(e) if e.to_string().contains(\"immutable\") => create_new_commit_instead(),\n    other => other,\n}","preventionTips":["Only amend commits on mutable workspace branches","Treat landed/integrated commits as read-only","Verify the Pick step's mutable flag before amend operations"],"tags":["git","amend","immutability","precondition"],"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"}