{"record":{"id":"e3fc998b5afb2a67","repo":"gitbutlerapp/gitbutler","slug":"deletions-or-additions-aren-t-well-defined-for-hunk-based-e3fc99","errorCode":null,"errorMessage":"Deletions or additions aren't well-defined for hunk-based operations - use the whole-file mode instead: '{wt_change.path}'","messagePattern":"Deletions or additions aren't well-defined for hunk-based operations - use the whole-file mode instead: '(.+?)'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-workspace/src/tree_manipulation/discard_worktree_changes.rs","lineNumber":140,"sourceCode":"                        &mut index,\n                        previous_path.as_bstr(),\n                        previous_state,\n                        file::RestoreMode::Deleted,\n                        &mut path_check,\n                        &mut initial_entries_len,\n                    )?;\n                    file::purge_and_restore_from_head_tree(\n                        &mut index,\n                        wt_change.path.as_bstr(),\n                        &mut path_check,\n                        initial_entries_len,\n                    )?;\n                }\n            }\n        } else {\n            match wt_change.status {\n                TreeStatus::Addition { .. } | TreeStatus::Deletion { .. } => {\n                    bail!(\n                        \"Deletions or additions aren't well-defined for hunk-based operations - use the whole-file mode instead: '{}'\",\n                        wt_change.path\n                    )\n                }\n                TreeStatus::Modification {\n                    previous_state,\n                    flags,\n                    ..\n                }\n                | TreeStatus::Rename {\n                    previous_state,\n                    flags,\n                    ..\n                } => {\n                    if flags.is_some_and(|f| f.is_typechange()) {\n                        bail!(\n                            \"Type-changed items can't be discard by hunks - use the whole-file mode instead\"\n                        )","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-workspace/src/tree_manipulation/discard_worktree_changes.rs#L122-L158","documentation":"Thrown by discard_workspace_changes when a worktree change to discard has status Addition or Deletion but the operation is hunk-based (hunks are being selectively discarded). Discarding 'some hunks' of a file that was newly added or entirely deleted is undefined, so the library rejects it and points to whole-file mode. It mirrors error 420 on the discard side.","triggerScenarios":"Calling discard_workspace_changes (via any of its public entry points such as all_file_types_deleted_in_worktree or replace_dir_with_file_discard_*) with a TreeStatus::Addition or TreeStatus::Deletion change while hunk-level discard is requested.","commonSituations":"Selective line-discarding in a worktree UI: the user picks lines to discard inside a newly created file or in a file whose deletion is staged in the worktree. Automated flows that pass every worktree change to hunk-based discard without filtering add/delete statuses.","solutions":["Route Addition/Deletion changes to a whole-file discard API instead of the hunk-based path.","Filter the change list before calling: only pass TreeStatus::Modification/Rename entries to hunk discard.","For a pure Addition, discard the whole file (delete it); for a Deletion, restore the whole file."],"exampleFix":"// before\nwt_changes.iter().for_each(|c| discard_workspace_changes(repo, c, hunks));\n\n// after\nfor c in wt_changes {\n    if matches!(c.status, TreeStatus::Addition{..} | TreeStatus::Deletion{..}) {\n        discard_whole_file(repo, c)?; // whole-file mode\n    } else {\n        discard_workspace_changes(repo, c, hunks)?;\n    }\n}","handlingStrategy":"validation","validationCode":"fn is_hunk_discardable(c: &WorktreeChange) -> bool {\n    !matches!(c.status, TreeStatus::Addition{..} | TreeStatus::Deletion{..})\n}","typeGuard":null,"tryCatchPattern":"// anyhow callers\nmatch discard_workspace_changes(...) {\n    Err(e) if e.to_string().contains(\"well-defined for hunk-based\") => discard_whole_file(change)?,\n    other => other?,\n}","preventionTips":["Partition changes into hunk-discardable and whole-file queues before calling the API","Disable line-level discard affordances for added/deleted files in the UI","Map statuses to the correct discard mode in one central helper"],"tags":["git","worktree","hunks"],"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"}