Hmbown/CodeWhale · error · anyhow::Error

Partial PR review: pass(es) completed, but the gate did not…

Error message

Partial PR review: {} pass(es) completed, but the gate did not read: {}. Raise --max-chars/--max-passes or shrink the PR, then re-run; publication: {}

What it means

The `codewhale review --pr` gate completed only some of its planned review passes and there are files the gate never read (listed in plan.manifest.skipped_files). Per issue #6285 AC3, the findings already produced are valid, but publication is refused: the gate must not pass on unread files. The error names what was skipped and the remedy so it reads as a limit, not a failed review.

Solutions

  1. Re-run with a higher --max-chars and/or --max-passes so all files fit within the planned passes
  2. Shrink the PR (split it into smaller PRs) so it fits within the review budget
  3. Treat the already-printed findings as real review output; fix them, then re-run the gate on the updated PR

Example fix

// before
codewhale review --pr 123 --max-chars 100000 --max-passes 2
// after
codewhale review --pr 123 --max-chars 250000 --max-passes 4
Defensive patterns

Strategy: validation

Validate before calling

// before running the gate, ensure the plan covers every file
if !plan.manifest.skipped_files.is_empty() {
    return Err(format!("review would skip {} files; raise --max-chars/--max-passes first", plan.manifest.skipped_files.len()).into());
}

Prevention

When it happens

Trigger: Running a multi-pass PR review where plan.passes.len() < planned passes and the manifest records skipped_files (PR too large for --max-chars/--max-passes limits), so the exit bails instead of publishing.

Common situations: Reviewing a large PR with default --max-chars/--max-passes; shrinking budgets to speed up CI; a review run interrupted by context limits.

Related errors


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

Appendix: source

Thrown at crates/tui/src/lib.rs:8914

        );
        if let Some((path, _)) = receipt {
            eprintln!("Review receipt written: {}", path.display());
        }
    } else {
        println!("{output}");
        if let Some((path, _)) = receipt {
            eprintln!("Review receipt written: {}", path.display());
        }
    }
    if let Some(plan) = &pr_plan
        && !plan.manifest.skipped_files.is_empty()
    {
        // #6285 AC3: the partial review above is real findings, already
        // printed and posted — but the gate must not pass on unread
        // files. The exit still fails, naming what the gate did not read
        // and the remedy, so it reads as limits rather than as "this PR
        // failed review".
        bail!(
            "Partial PR review: {} pass(es) completed, but the gate did not read: {}. Raise --max-chars/--max-passes or shrink the PR, then re-run; publication: {}",
            plan.passes.len(),
            crate::tools::review::format_skipped_files(&plan.manifest.skipped_files),
            publication.as_str()
        );
    }
    Ok(())
}

/// Criterion 4 (no silent caps): whatever a budget stop leaves unread is
/// named by file, never silently dropped — including files the plan itself
/// skipped before the first pass ran (#6285 AC4). A free function so tests
/// can pin the note without running a review.
fn pr_review_unreviewed_note(
    plan: Option<&crate::tools::review::PrReviewPlan>,
    completed_passes: usize,
) -> String {
    let Some(plan) = plan else {

View on GitHub (pinned to 73e0f67d83)