Hmbown/CodeWhale · error
Incomplete PR diff: a text hunk is truncated or malformed
Error message
Incomplete PR diff: a text hunk is truncated or malformed
What it means
complete_file_set walks the fetched `git diff` line by line, tracking how many hunk lines remain per file. When a hunk ends with fewer remaining context/addition/deletion lines than the header promised — or contains a line the state machine does not recognize — the diff is truncated or malformed and the review is rejected rather than performed on partial content.
Solutions
- Re-fetch the diff (`gh pr diff`/`git diff` path in fetch_diff) and confirm the byte count matches the PR's additions+deletions plus headers
- Remove any pager/filter wrappers between git and the tool (`GIT_PAGER=cat`, `core.pager=cat`, no external diff drivers)
- Verify no output truncation happened (check the 64KiB bounded readers in run_command and any size limits); re-run the review on the complete diff
Example fix
// before: piping diff through a pager/mangler git diff base...head | less // after: plain, no-ext-diff, no pager git diff --no-ext-diff --no-color base...head
Defensive patterns
Strategy: validation
Validate before calling
// verify hunk line counts before review
for hunk in diff.lines().filter(|l| l.starts_with("@@")) {
let (_, old, new) = parse_hunk_header(hunk).ok_or("bad header")?;
// count following +/ -/space lines and compare to old/new
} Try / catch
match diff_with(&view) {
Err(e) if e.to_string().contains("truncated or malformed") => eprintln!("diff incomplete; refetch with GIT_PAGER=cat git diff --no-ext-diff"),
other => other?,
} Prevention
- Fetch diffs without pagers, colors, or post-processing filters
- Keep diff output under any size caps or raise them for large PRs
- Never reflow or line-wrap diff text before feeding it to the tool
When it happens
Trigger: The diff text emitted by `git diff` was cut off (output limit, killed process, corrupted pipe) or a hunk body has fewer lines than the @@ -a,b +c,d @@ header counts, leaving the line matcher at a non-continuation token.
Common situations: Hitting the bounded stdout read cap on very large diffs; a pager or filter mangling output (missing --no-ext-diff equivalent); tools post-processing the diff text and dropping lines; copying diffs through processes that trim trailing context.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Incomplete PR diff: a file patch is missing
- Incomplete PR diff: received
- PR diff contains binary metadata without exact full object…
- Incomplete PR diff: malformed hunk header
- A full Git history is required to establish the PR merge…
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/3c0496db60184208.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tools/review_pr.rs:191
let mut has_patch = false;
let mut has_full_index = false;
for line in diff.lines() {
if remaining != (0, 0) {
match line.as_bytes().first() {
Some(b'+') if remaining.1 > 0 => {
remaining.1 -= 1;
additions += 1;
}
Some(b'-') if remaining.0 > 0 => {
remaining.0 -= 1;
deletions += 1;
}
Some(b' ') if remaining.0 > 0 && remaining.1 > 0 => {
remaining.0 -= 1;
remaining.1 -= 1;
}
Some(b'\\') => {}
_ => bail!("Incomplete PR diff: a text hunk is truncated or malformed"),
}
continue;
}
if line.starts_with("diff --git ") {
if files > 0 && !has_patch {
bail!("Incomplete PR diff: a file patch is missing");
}
files += 1;
has_patch = false;
has_full_index = false;
} else if line.starts_with("index ") {
has_full_index = full_index_objects(line);
} else if let Some((_, old, new)) = super::review_hunks::parse_hunk_header(line) {
remaining = (old, new);
has_patch = true;
} else if line.starts_with("@@") {
bail!("Incomplete PR diff: malformed hunk header");
} else if [View on GitHub (pinned to 73e0f67d83)