{"record":{"id":"224e785a4c149758","repo":"Hmbown/CodeWhale","slug":"pr-review-plan-covers-0-of-file-patches-within-max-chars","errorCode":null,"errorMessage":"PR review plan covers 0 of {} file patches within {max_chars} characters per pass and {max_passes} pass(es); skipped: {}. No review was run or posted.","messagePattern":"PR review plan covers 0 of (.+?) file patches within (.+?) characters per pass and (.+?) pass\\(es\\); skipped: (.+?)\\. No review was run or posted\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/tools/review.rs","lineNumber":569,"sourceCode":"    }\n    // Passes beyond the budget are skipped in diff order, never fatal. The\n    // plan reviews what fits and names the rest.\n    for group in grouped.split_off(max_passes.min(grouped.len())) {\n        for piece in group {\n            let label = piece.label;\n            let chars = super::review_pr::model_diff(&piece.diff).chars().count();\n            skipped.push(PrReviewSkippedFile {\n                file: label,\n                reason: SKIP_REASON_BEYOND_MAX_PASSES.to_string(),\n                chars,\n            });\n        }\n    }\n\n    // Only a plan that covers nothing still errors — and even then it\n    // names every skipped file, so the failure reads as limits, not as a\n    // verdict on the code.\n    anyhow::ensure!(\n        !grouped.is_empty(),\n        \"PR review plan covers 0 of {} file patches within {max_chars} characters per pass and {max_passes} pass(es); skipped: {}. No review was run or posted.\",\n        view.changed_files,\n        format_skipped_files(&skipped)\n    );\n\n    let passes = grouped\n        .into_iter()\n        .enumerate()\n        .map(|(index, pieces)| {\n            let diff = pieces\n                .iter()\n                .map(|piece| -> &str { &piece.diff })\n                .collect::<String>();\n            let labels = pieces\n                .iter()\n                .map(|piece| piece.label.clone())\n                .collect::<Vec<_>>();","sourceCodeStart":551,"sourceCodeEnd":587,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/tools/review.rs#L551-L587","documentation":"If the plan groups zero passes — every file patch was skipped as oversized for the per-pass char budget — no review can run. This error names every skipped file plus the limits so the failure reads as a limits problem, not a code verdict.","triggerScenarios":"max_chars smaller than the largest single file patch, so every file is skipped; changed_files > 0 but all patches exceed the per-pass budget even after splitting; max_passes too low to fit any piece after splitting.","commonSituations":"max_chars configured far too low (e.g. 1000 chars) for a real PR; a single massive generated file dominating the diff; mis-set budget derived from an exhausted context budget.","solutions":["Increase review max_chars so at least one pass has content (e.g. 50_000+)","Increase max_passes so split pieces fit across passes","Split the PR into smaller reviews, or exclude generated/vendored files from the diff","Inspect the skipped list in the message to see which files drove the overflow"],"exampleFix":"// before\n\"review\": { \"max_chars\": 500, \"max_passes\": 1 }\n// after\n\"review\": { \"max_chars\": 60000, \"max_passes\": 3 }","handlingStrategy":"validation","validationCode":"if max_chars < largest_patch_len { bail!(\"max_chars {} smaller than largest file patch\", max_chars); }","typeGuard":null,"tryCatchPattern":"match plan_pr_review(...) { Err(e) if e.to_string().contains(\"covers 0 of\") => retry_with_larger_budget().await, ... }","preventionTips":["Set max_chars comfortably above the largest expected file patch","Exclude generated/vendored files from review diffs","Derive max_chars from measured diff size, not a fixed small constant"],"tags":["review","limits","configuration"],"backgroundTag":"invalid-config-value","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"}