{"record":{"id":"62bce288dcb22f1c","repo":"Hmbown/CodeWhale","slug":"incomplete-pr-diff-malformed-hunk-header","errorCode":null,"errorMessage":"Incomplete PR diff: malformed hunk header","messagePattern":"Incomplete PR diff: malformed hunk header","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/tools/review_pr.rs","lineNumber":208,"sourceCode":"                Some(b'\\\\') => {}\n                _ => bail!(\"Incomplete PR diff: a text hunk is truncated or malformed\"),\n            }\n            continue;\n        }\n        if line.starts_with(\"diff --git \") {\n            if files > 0 && !has_patch {\n                bail!(\"Incomplete PR diff: a file patch is missing\");\n            }\n            files += 1;\n            has_patch = false;\n            has_full_index = false;\n        } else if line.starts_with(\"index \") {\n            has_full_index = full_index_objects(line);\n        } else if let Some((_, old, new)) = super::review_hunks::parse_hunk_header(line) {\n            remaining = (old, new);\n            has_patch = true;\n        } else if line.starts_with(\"@@\") {\n            bail!(\"Incomplete PR diff: malformed hunk header\");\n        } else if [\n            \"new file mode \",\n            \"deleted file mode \",\n            \"old mode \",\n            \"new mode \",\n            \"rename from \",\n            \"rename to \",\n            \"GIT binary patch\",\n        ]\n        .iter()\n        .any(|prefix| line.starts_with(prefix))\n        {\n            has_patch = true;\n        } else if line.starts_with(\"Binary files \") {\n            if !has_full_index {\n                bail!(\n                    \"PR diff contains binary metadata without exact full object IDs; complete local Git objects are required\"\n                );","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/tools/review_pr.rs#L190-L226","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Regenerate the diff with default formatting: `git diff --no-ext-diff --no-color -U3 base...head`","Check repo config for diff options that alter hunk output (diff.context, diff.wordDiff, diff.functionContext) and unset them","Inspect the offending `@@` line in the raw diff to confirm whether the text was truncated or rewritten; re-fetch if so"],"exampleFix":"// before: word-diff enabled in config changes @@ header output\ngit config diff.wordDiff true\n// after: plain unified diff only\ngit config --unset diff.wordDiff\ngit diff --no-ext-diff --no-color base...head","handlingStrategy":"validation","validationCode":"// pre-validate hunk headers match the canonical unified format\nlet re = regex::Regex::new(r\"^@@ -\\d+(?:,\\d+)? \\+\\d+(?:,\\d+)? @@\").unwrap();\nfor l in diff.lines().filter(|l| l.starts_with(\"@@\")) {\n    assert!(re.is_match(l), \"non-canonical hunk header: {l}\");\n}","typeGuard":null,"tryCatchPattern":"match diff_with(&view) {\n    Err(e) if e.to_string().contains(\"malformed hunk header\") => eprintln!(\"regenerate diff with plain git diff --no-ext-diff --no-color -U3\"),\n    other => other?,\n}","preventionTips":["Disable diff options that alter hunk format (wordDiff, functionContext, custom context counts) in the review repo","Feed the tool raw git output, never diffs rewritten by other tools","Use --no-ext-diff to keep header format canonical"],"tags":["git","diff","parse-error","format"],"backgroundTag":"invalid-argument-format","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}