gitbutlerapp/gitbutler · error

Type-changed items can't be discard by hunks - use the…

Error message

Type-changed items can't be discard by hunks - use the whole-file mode instead

What it means

Thrown by discard_workspace_changes when a modification/rename change is flagged as a typechange (e.g. file became a symlink or executable transition) and the caller attempts hunk-level discard. Hunk diffs are not meaningful across type changes, so only whole-file mode is allowed. Note the message contains a typo ('can't be discard') but is unconditional for any is_typechange() flag.

Solutions

  1. Discard the entire change for typechanged paths rather than selected hunks.
  2. Check change flags for is_typechange() before entering the hunk path and split such changes into a whole-file discard queue.
  3. If only the mode bit changed, restore the whole entry to its previous state with whole-file mode.

Example fix

// before
hunk::restore_state_to_worktree(wt_change, previous_state, hunks)?;

// after
if wt_change.flags.is_some_and(|f| f.is_typechange()) {
    whole_file_restore(wt_change, previous_state)?;
} else {
    hunk::restore_state_to_worktree(wt_change, previous_state, hunks)?;
}
Defensive patterns

Strategy: validation

Validate before calling

fn is_typechange(c: &WorktreeChange) -> bool {
    c.flags.is_some_and(|f| f.is_typechange())
}

Try / catch

// fall back to whole-file on this specific bail
if let Err(e) = discard_workspace_changes(...) {
    if e.to_string().contains("Type-changed") { whole_file_discard(change)?; } else { return Err(e); }
}

Prevention

When it happens

Trigger: Calling discard_workspace_changes with a change whose flags include is_typechange() while requesting hunk-scoped restoration; typically a path whose git entry kind changed between Blob, BlobExecutable, Link, etc.

Common situations: A user chmod +x'd a file, or replaced a regular file with a symlink (common on macOS/Linux), then tries to discard selected lines instead of the whole change. Tools that sync permission/symlink changes from other systems.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18). Data as JSON: /api/errors/459f05af57bac379. Report an issue: GitHub.

Appendix: source

Thrown at crates/but-workspace/src/tree_manipulation/discard_worktree_changes.rs:156

            match wt_change.status {
                TreeStatus::Addition { .. } | TreeStatus::Deletion { .. } => {
                    bail!(
                        "Deletions or additions aren't well-defined for hunk-based operations - use the whole-file mode instead: '{}'",
                        wt_change.path
                    )
                }
                TreeStatus::Modification {
                    previous_state,
                    flags,
                    ..
                }
                | TreeStatus::Rename {
                    previous_state,
                    flags,
                    ..
                } => {
                    if flags.is_some_and(|f| f.is_typechange()) {
                        bail!(
                            "Type-changed items can't be discard by hunks - use the whole-file mode instead"
                        )
                    }
                    hunk::restore_state_to_worktree(
                        wt_change,
                        previous_state,
                        &mut spec.hunk_headers,
                        &mut path_check,
                        &mut pipeline,
                        &index,
                        context_lines,
                    )?;
                    if !spec.hunk_headers.is_empty() {
                        dropped.push(spec);
                        continue;
                    }
                }
            }

View on GitHub (pinned to 58e5313667)