gitbutlerapp/gitbutler · warning
u32 -> i32 conversion overflow
Error message
u32 -> i32 conversion overflow
What it means
InputDiffHunk::net_lines() computes new_lines - old_lines as an i64 and then narrows to i32. The error is thrown when the arithmetic subtraction would underflow/overflow at the i64 level or the result does not fit into an i32, which cannot happen with realistic u32 line counts but is guarded anyway because `checked_signed_diff` is not yet stable.
Solutions
- Verify the InputDiffHunk was built from a real unified diff, not synthetic values
- Clamp or validate new_lines/old_lines before constructing the hunk
- If truly needed, change the return type to i64 to eliminate the i32 narrowing
Example fix
// before let net = hunk.net_lines()?; // after let net = i64::from(hunk.new_lines()) - i64::from(hunk.old_lines()); // no i32 narrowing
Defensive patterns
Strategy: validation
Validate before calling
fn net_lines_safe(new_lines: u32, old_lines: u32) -> Option<i32> {
let diff = i64::from(new_lines) - i64::from(old_lines);
i32::try_from(diff).ok()
}
// call net_lines() only when this returns Some Try / catch
// Rust: match on Result
match hunk.net_lines() {
Ok(n) => use_net(n),
Err(e) => log::warn!("net_lines unavailable: {e:#}"),
} Prevention
- Only construct InputDiffHunk from real git diffs
- Validate line-count fields when deserializing from untrusted sources
When it happens
Trigger: Calling net_lines() on an InputDiffHunk whose new_lines/old_lines combination yields a value outside i32 range (theoretically |diff| > 2^31-1, impossible for real diffs since both operands are u32); in practice it indicates corrupted or adversarially constructed hunk input.
Common situations: Feeding fabricated or fuzzed diff data into the hunk-dependency machinery rather than real git diffs; deserializing InputDiffHunk from untrusted JSON with huge line counts.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Subtraction overflow
- a committed transaction always materializes a workspace
- anchor is always present in the order at this point
- another pre-commit hook is already using the repository…
- askpass broker must be initialized
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/04d5b5e246292e69.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but-hunk-dependency/src/input.rs:60
pub struct InputDiffHunk {
/// The 1-based line number at which the previous version of the file started.
pub old_start: u32,
/// The non-zero amount of lines included in the previous version of the file.
pub old_lines: u32,
/// The 1-based line number at which the new version of the file started.
pub new_start: u32,
/// The non-zero amount of lines included in the new version of the file.
pub new_lines: u32,
}
impl InputDiffHunk {
/// Compute the amount of lines that are left when subtracting old-lines from new-lines.
pub fn net_lines(&self) -> anyhow::Result<i32> {
// TODO: use `checked_signed_diff` instead when stable.
(self.new_lines as i64)
.checked_sub(self.old_lines as i64)
.and_then(|n| i32::try_from(n).ok())
.ok_or(anyhow!("u32 -> i32 conversion overflow"))
}
}
impl InputDiffHunk {
/// Create a new instance from unified `diff`.
pub fn from_unified_diff(
but_core::unified_diff::DiffHunk {
old_start,
old_lines,
new_start,
new_lines,
diff: _,
}: &but_core::unified_diff::DiffHunk,
) -> Self {
InputDiffHunk {
old_start: *old_start,
old_lines: *old_lines,
new_start: *new_start,View on GitHub (pinned to 58e5313667)