gitbutlerapp/gitbutler · error · anyhow::Error
Unexpected hunk with neither newlines or oldlines being 0
Error message
Unexpected hunk with neither newlines or oldlines being 0
What it means
When GitButler computes which hunks to commit, the primary algorithm must produce hunks in order; if not, it retries with `to_additive_hunks_fallback`, which only understands purely additive (old_lines == 0) or purely subtractive (new_lines == 0) hunks. A selected hunk with both counts non-zero (a modification) reaching this fallback trips the bail — the fallback was never designed for replacement hunks.
Source
Thrown at crates/but-core/src/tree/mod.rs:471
new_start,
new_lines,
}| {
if old_lines == 0 {
Ok(HunkHeader {
old_start: 0,
old_lines: 0,
new_start,
new_lines,
})
} else if new_lines == 0 {
Ok(HunkHeader {
old_start,
old_lines,
new_start: 0,
new_lines: 0,
})
} else {
bail!("Unexpected hunk with neither newlines or oldlines being 0");
}
},
)
.collect::<Result<_, _>>()?;
let (hunks_to_commit, rejected) =
to_additive_hunks_fallback(hunks, worktree_hunks, worktree_hunks_no_context);
if !in_order(&hunks_to_commit) {
bail!(
"Alternative hunks algorithms still didn't produce properly ordered hunks or saw duplicate inputs: {hunks_to_commit:?}"
);
}
(hunks_to_commit, rejected)
} else {
(hunks_to_commit, rejected)
};
Ok(res)
}
View on GitHub (pinned to caf1f223d3)
Solutions
- Commit the whole file instead of individual hunks for the affected file.
- Change the hunk selection (e.g. include the full modification hunk rather than splitting around it) and retry.
- Update GitButler — hunk-selection algorithms are actively improved and this is a known class of fallback limitation.
- Capture the hunk headers (logged at info level before the fallback runs) and file a bug report.
Defensive patterns
Strategy: fallback
Type guard
// Rust — a selected hunk the fallback algorithm can handle must be purely additive or purely subtractive
fn is_pure_hunk(h: &but_diff::HunkHeader) -> bool {
h.old_lines == 0 || h.new_lines == 0
} Try / catch
// Fall back to committing the whole file when hunk-level commit fails
match commit_selected_hunks(path, hunks) {
Ok(()) => Ok(()),
Err(err) if err.to_string().contains("Unexpected hunk") => {
tracing::warn!("hunk fallback failed for {path}; committing whole file");
commit_whole_file(path)
}
Err(err) => Err(err),
} Prevention
- Let the worktree settle (no concurrent editor/format-on-save) before making hunk-level selections.
- Prefer selecting whole modification hunks over split fragments around them.
- Keep GitButler updated; capture the info-level log with hunk headers when reporting.
When it happens
Trigger: Partially staging hunks such that the primary algorithm emits out-of-order/duplicate hunks and the retry set contains a modification hunk — typically hand-picked hunk selections on files with interleaved adds, deletes and edits.
Common situations: Selecting individual modified hunks in the GitButler UI on files with mixed changes; hunk selections produced after external tools (formatters, editors) race the diff computation.
Related errors
- Alternative hunks algorithms still didn't produce properly o
- Failed to communicate with LM Studio server: ${error instanc
- When using LM Studio, you must provide a valid endpoint
- worktree-changes are always set if there are hunks
- Commit {} is not in the applied workspace
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/fc27d22626f3a3e2.
Report an issue: GitHub.