gitbutlerapp/gitbutler · error · anyhow::Error
Alternative hunks algorithms still didn't produce properly o
Error message
Alternative hunks algorithms still didn't produce properly ordered hunks or saw duplicate inputs: {hunks_to_commit:?} What it means
After the primary hunk algorithm produced out-of-order results, GitButler re-normalizes each hunk and reruns `to_additive_hunks_fallback`, then re-checks ordering with `in_order()`. If the fallback's output is still not strictly increasing (or it saw duplicate inputs), this bail fires with the offending hunk list. It marks an internal limitation of the hunk-to-commit translation, not user misconfiguration.
Source
Thrown at crates/but-core/src/tree/mod.rs:479
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)
}
/// This algorithm is better when the basic one fails, but both have their merit.
/// Right now this is a brute-force one or the other approach, but we could also apply them selectively.
/// Note that what we really want to simulate is what the UI shows. But since the UI also doesn't really know hunks,
/// we have to fiddle it together here, at least we know the hunks themselves.
///
/// Note that this algorithm is kind of the opposite of what people would expect if it's run where `to_additive_hunks()` works.
/// But here we are… just making this work.
#[expect(clippy::indexing_slicing)]View on GitHub (pinned to caf1f223d3)
Solutions
- Retry the operation after the worktree is quiescent (no concurrent editor/formatter writing the file).
- Commit the file in full instead of hunk-by-hunk.
- Update GitButler; attach the `tracing` log line ('Using alternative hunk algorithm…') and the hunk list from the error to a bug report.
Defensive patterns
Strategy: fallback
Try / catch
match compute_hunks_to_commit(...) {
Ok(hunks) => hunks,
Err(err) if err.to_string().contains("Alternative hunks algorithms") => {
// internal algorithm limitation: degrade gracefully to file-level commit
tracing::warn!("{err:#}");
commit_whole_file(path)?;
Vec::new()
}
Err(err) => return Err(err),
} Prevention
- Recompute diffs immediately before committing so worktree and selection diffs agree.
- Avoid mixing line-ending rewrites with content edits in the same hunk-selection round.
- Attach the printed hunk list to a bug report — this error exists to expose algorithm gaps.
When it happens
Trigger: Hunk selections whose worktree diff context disagrees with the selection diff (file changed between computing the two), or pathological interleaved selections where both ordering heuristics fail.
Common situations: Files being edited concurrently while the user selects hunks in the UI; very large files with many adjacent small hunks; line-ending changes mixed with content changes.
Related errors
- Unexpected hunk with neither newlines or oldlines being 0
- 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/33a8d31a1bdc21fb.
Report an issue: GitHub.