GitoxideLabs/gitoxide · error
BUG: hunks are never zero-sized
Error message
BUG: hunks are never zero-sized
What it means
When coalescing adjacent blame hunks in `gix-blame`, the merged length is computed as `NonZeroU32::new(end - start).expect("BUG: hunks are never zero-sized")`. The invariant is that every tracked hunk spans at least one line, so the difference is positive; a zero would mean empty hunks were recorded earlier in the algorithm.
Solutions
- Upgrade gix-blame to the latest version where the edge case may be fixed
- Reduce the offending repository/commit to a minimal repro and file an upstream issue
- As a workaround, blame a specific revision range that avoids the boundary commit
Example fix
// defensive upstream fix
let len = (current_source_range.end - previous_source_range.start) as u32;
let len = NonZeroU32::new(len).expect("BUG: hunks are never zero-sized");
// caller-side: no fix possible; upgrade the crate Defensive patterns
Strategy: try-catch
Try / catch
let res = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| gix_blame(...)));
match res { Ok(v) => v, Err(_) => /* fall back to `git blame` CLI */ fallback_blame() } Prevention
- Pin recent gix-blame versions
- Test blame on boundary/empty-file commits in CI
- Keep a git CLI fallback for blame in tooling
When it happens
Trigger: Running blame (public `BlameEntry`-producing flow) on inputs where adjacent hunks have `current_source_range.end == previous_source_range.start`, i.e. a zero-length range slipping through hunk computation — an internal algorithm bug rather than bad user input.
Common situations: Edge-case repository histories (empty files, boundary commits) triggering a blame implementation bug; usually reported and fixed in a patch release.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- only value and unspecified are possible here
- parent-match assures this
- upper match already assured we only deal with blobs
- fixed size array with three items
- internal nodes have no object ID key
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/611cc52bd2a756ea.
Report an issue: GitHub.
Appendix: source
Thrown at gix-blame/src/file/function.rs:480
.into_iter()
.fold(Vec::with_capacity(len), |mut acc, entry| {
let previous_entry = acc.last();
if let Some(previous_entry) = previous_entry {
let previous_blamed_range = previous_entry.range_in_blamed_file();
let current_blamed_range = entry.range_in_blamed_file();
let previous_source_range = previous_entry.range_in_source_file();
let current_source_range = entry.range_in_source_file();
if previous_entry.commit_id == entry.commit_id
&& previous_blamed_range.end == current_blamed_range.start
// As of 2024-09-19, the check below only is in `git`, but not in `libgit2`.
&& previous_source_range.end == current_source_range.start
{
let coalesced_entry = BlameEntry {
start_in_blamed_file: previous_blamed_range.start as u32,
start_in_source_file: previous_source_range.start as u32,
len: NonZeroU32::new((current_source_range.end - previous_source_range.start) as u32)
.expect("BUG: hunks are never zero-sized"),
commit_id: previous_entry.commit_id,
source_file_name: previous_entry.source_file_name.clone(),
};
acc.pop();
acc.push(coalesced_entry);
} else {
acc.push(entry);
}
acc
} else {
acc.push(entry);
acc
}
})
}View on GitHub (pinned to e73179060b)