{"record":{"id":"6d76c81d26dc0ffd","repo":"affaan-m/ECC","slug":"selected-hunk-is-not-staged","errorCode":null,"errorMessage":"selected hunk is not staged","messagePattern":"selected hunk is not staged","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"ecc2/src/worktree/mod.rs","lineNumber":416,"sourceCode":"        }))\n    }\n}\n\npub fn stage_hunk(worktree: &WorktreeInfo, hunk: &GitPatchHunk) -> Result<()> {\n    if hunk.section != GitPatchSectionKind::Unstaged {\n        anyhow::bail!(\"selected hunk is already staged\");\n    }\n    git_apply_patch(\n        &worktree.path,\n        &[\"--cached\"],\n        &hunk.patch,\n        \"stage selected hunk\",\n    )\n}\n\npub fn unstage_hunk(worktree: &WorktreeInfo, hunk: &GitPatchHunk) -> Result<()> {\n    if hunk.section != GitPatchSectionKind::Staged {\n        anyhow::bail!(\"selected hunk is not staged\");\n    }\n    git_apply_patch(\n        &worktree.path,\n        &[\"-R\", \"--cached\"],\n        &hunk.patch,\n        \"unstage selected hunk\",\n    )\n}\n\npub fn reset_hunk(\n    worktree: &WorktreeInfo,\n    entry: &GitStatusEntry,\n    hunk: &GitPatchHunk,\n) -> Result<()> {\n    if entry.untracked {\n        anyhow::bail!(\"cannot reset hunks for untracked files\");\n    }\n","sourceCodeStart":398,"sourceCodeEnd":434,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/ecc2/src/worktree/mod.rs#L398-L434","documentation":"unstage_hunk unstages a hunk by reverse-applying its patch to the index (`git apply -R --cached`) and therefore requires the hunk to come from the staged section. If the hunk's section is Unstaged, the library throws this precondition error because an unstaged hunk cannot be removed from the index.","triggerScenarios":"Calling unstage_hunk(worktree, hunk) with hunk.section == GitPatchSectionKind::Unstaged, typically from UI code that wires both staged and unstaged diff panels to a single 'unstage' handler.","commonSituations":"Reusing one context menu for both diff sections; stale hunk objects captured before a previous staging operation moved the hunk between sections.","solutions":["Verify hunk.section == GitPatchSectionKind::Staged before calling unstage_hunk.","Re-fetch the patch view after every stage/unstage/reset operation so hunk sections reflect current index state.","Route unstaged hunks to stage_hunk (or discard via reset_hunk) instead."],"exampleFix":"// before\nunstage_hunk(&worktree, &hunk)?;\n\n// after\nif hunk.section == GitPatchSectionKind::Staged {\n    unstage_hunk(&worktree, &hunk)?;\n}","handlingStrategy":"type-guard","validationCode":"if hunk.section != GitPatchSectionKind::Staged {\n    return Err(anyhow!(\"hunk is not staged; nothing to unstage\"));\n}","typeGuard":"fn is_unstageable(hunk: &GitPatchHunk) -> bool {\n    matches!(hunk.section, GitPatchSectionKind::Staged)\n}","tryCatchPattern":"match unstage_hunk(&worktree, &hunk) {\n    Ok(()) => refresh_patch_view(),\n    Err(e) if e.to_string().contains(\"not staged\") => refresh_patch_view(),\n    Err(e) => eprintln!(\"unstage hunk failed: {e:#}\"),\n}","preventionTips":["Only call unstage_hunk for hunks rendered in the staged diff panel.","Refresh hunk data after any staging operation; section membership is volatile.","Use a single dispatcher that routes by hunk.section instead of per-panel handlers."],"tags":["git","precondition","invalid-state"],"backgroundTag":"invalid-state-transition","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}