{"record":{"id":"e540eaf958d38482","repo":"Hmbown/CodeWhale","slug":"complete-pr-file-patch-requires-patch-chars-characters","errorCode":null,"errorMessage":"Complete PR file patch {} requires {patch_chars} characters, exceeding the per-pass review limit of {max_chars}. No review was run or posted.","messagePattern":"Complete PR file patch (.+?) requires (.+?) characters, exceeding the per-pass review limit of (.+?)\\. No review was run or posted\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/tools/review.rs","lineNumber":338,"sourceCode":"    // replayed into every part so each part stays a self-describing patch;\n    // no line is elided, shortened or reordered. Sizes use the model\n    // representation, so a binary payload already omitted there can never\n    // drive a split.\n    let mut pieces: Vec<PrReviewPiece<'_>> = Vec::new();\n    for patch in patches {\n        let patch_chars = super::review_pr::model_diff(patch).chars().count();\n        if patch_chars <= max_chars {\n            pieces.push(PrReviewPiece {\n                diff: Cow::Borrowed(patch),\n                label: patch_label(patch),\n                header_bytes: 0,\n            });\n            continue;\n        }\n        let (header, hunks) = pr_file_hunks(patch);\n        let header_chars = header.chars().count();\n        let largest_hunk_chars = hunks.iter().map(|hunk| hunk.chars().count()).max();\n        anyhow::ensure!(\n            largest_hunk_chars.is_some_and(|hunk_chars| header_chars + hunk_chars <= max_chars),\n            \"Complete PR file patch {} requires {patch_chars} characters, exceeding the per-pass review limit of {max_chars}. No review was run or posted.\",\n            patch_label(patch)\n        );\n        let label = patch_label(patch);\n        let mut parts: Vec<String> = Vec::new();\n        let mut part = String::from(header);\n        let mut part_chars = header_chars;\n        for hunk in hunks {\n            let hunk_chars = hunk.chars().count();\n            if part_chars > header_chars && part_chars + hunk_chars > max_chars {\n                parts.push(std::mem::replace(&mut part, String::from(header)));\n                part_chars = header_chars;\n            }\n            part.push_str(hunk);\n            part_chars += hunk_chars;\n        }\n        parts.push(part);","sourceCodeStart":320,"sourceCodeEnd":356,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/crates/tui/src/tools/review.rs#L320-L356","documentation":"When splitting a file patch into passes, plan_pr_review guarantees each pass is self-contained. This ensure! fires when a single hunk plus its file header exceeds the entire per-pass max_chars budget, meaning no split at complete-hunk boundaries can ever fit that file. The review aborts entirely and posts nothing rather than reviewing a partial file.","triggerScenarios":"A single file in the PR contains one enormous hunk (a generated file, minified bundle, lockfile, or data file) whose hunk plus header exceeds max_chars while planning the review.","commonSituations":"Reviewing PRs that touch vendored dependencies, JSON snapshots, or generated code; max_chars configured too small for large-hunk repos; a new binary-ish text file added to the PR.","solutions":["Increase max_chars so the largest hunk plus header fits within one pass","Exclude the oversized file from review (e.g. .gitattributes or review ignore config) or split it in the PR","Regenerate/refactor the file so hunks are smaller (avoid single-giant-hunk generated files)"],"exampleFix":"// before\nplan_pr_review(diff, view, 8_000, passes)? // hunk of 12k chars fails\n// after\nplan_pr_review(diff, view, 16_000, passes)? // largest hunk + header fits","handlingStrategy":"validation","validationCode":"let fits = |patch: &str, max: usize| {\n    let (header, hunks) = split_patch(patch);\n    hunks.iter().all(|h| header.chars().count() + h.chars().count() <= max)\n};","typeGuard":null,"tryCatchPattern":"match plan_pr_review(...) { Err(e) if e.to_string().contains(\"exceeding the per-pass review limit\") => raise_budget_or_exclude_file(e), other => other }","preventionTips":["Pre-scan PRs for generated/minified/lockfile files and exclude them from review","Set max_chars at least as large as your repo's largest expected hunk plus header","Avoid committing single-giant-hunk generated files"],"tags":["payload-size","diff-parsing","budget"],"backgroundTag":"payload-too-large","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}