Hmbown/CodeWhale · error

Incomplete PR diff: malformed hunk header

Error message

Incomplete PR diff: malformed hunk header

What it means

complete_file_set recognizes hunk headers through review_hunks::parse_hunk_header. A line starting with `@@` that the parser cannot turn into (old, new) counts is a malformed hunk header — the diff's line accounting cannot proceed safely, so the whole diff is rejected.

Solutions

  1. Regenerate the diff with default formatting: `git diff --no-ext-diff --no-color -U3 base...head`
  2. Check repo config for diff options that alter hunk output (diff.context, diff.wordDiff, diff.functionContext) and unset them
  3. Inspect the offending `@@` line in the raw diff to confirm whether the text was truncated or rewritten; re-fetch if so

Example fix

// before: word-diff enabled in config changes @@ header output
git config diff.wordDiff true
// after: plain unified diff only
git config --unset diff.wordDiff
git diff --no-ext-diff --no-color base...head
Defensive patterns

Strategy: validation

Validate before calling

// pre-validate hunk headers match the canonical unified format
let re = regex::Regex::new(r"^@@ -\d+(?:,\d+)? \+\d+(?:,\d+)? @@").unwrap();
for l in diff.lines().filter(|l| l.starts_with("@@")) {
    assert!(re.is_match(l), "non-canonical hunk header: {l}");
}

Try / catch

match diff_with(&view) {
    Err(e) if e.to_string().contains("malformed hunk header") => eprintln!("regenerate diff with plain git diff --no-ext-diff --no-color -U3"),
    other => other?,
}

Prevention

When it happens

Trigger: A hunk header like `@@ ... @@` with non-numeric or missing range specs (e.g. `@@ -1 +1 @@` forms the parser does not accept, or a mangled header produced by truncation/rewriting of the diff text).

Common situations: Diff text round-tripped through another tool that reflows whitespace or line-wraps long headers; unusual git diff options (function-context, word-diff) enabled in repo config changing header format; corrupted output from an external diff driver.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/62bce288dcb22f1c. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/tools/review_pr.rs:208

                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 [
            "new file mode ",
            "deleted file mode ",
            "old mode ",
            "new mode ",
            "rename from ",
            "rename to ",
            "GIT binary patch",
        ]
        .iter()
        .any(|prefix| line.starts_with(prefix))
        {
            has_patch = true;
        } else if line.starts_with("Binary files ") {
            if !has_full_index {
                bail!(
                    "PR diff contains binary metadata without exact full object IDs; complete local Git objects are required"
                );

View on GitHub (pinned to 73e0f67d83)