Hmbown/CodeWhale · error
Review max_passes must be from 1 to
Error message
Review max_passes must be from 1 to {MAX_REVIEW_PASSES} What it means
plan_pr_review parameter validation: max_passes must lie between 1 and MAX_REVIEW_PASSES; out-of-bound values are rejected before any pass planning, keeping the degradation manifest's pass count bounded.
Solutions
- Set max_passes to 1..=MAX_REVIEW_PASSES in config
- Clamp at the call site: `let max_passes = max_passes.clamp(1, MAX_REVIEW_PASSES);`
- Check stored config against the current MAX_REVIEW_PASSES constant after upgrading
Example fix
// before let max_passes = 0; plan_pr_review(diff, &view, max_chars, max_passes)?; // after let max_passes = max_passes.clamp(1, MAX_REVIEW_PASSES); plan_pr_review(diff, &view, max_chars, max_passes)?;
Defensive patterns
Strategy: validation
Validate before calling
if !(1..=MAX_REVIEW_PASSES).contains(&max_passes) { return Err(anyhow!("max_passes out of range")); } Try / catch
match plan_pr_review(...) { Err(e) if e.to_string().contains("max_passes") => clamp_and_retry(1, MAX_REVIEW_PASSES), ... } Prevention
- Clamp config values with .clamp(1, MAX_REVIEW_PASSES) at load time
- Validate review config once at startup, not per call
- Re-check stored config after MAX_REVIEW_PASSES changes between versions
When it happens
Trigger: Calling plan_pr_review with max_passes = 0 or exceeding MAX_REVIEW_PASSES, usually from config (review.max_passes) or a computed pass count.
Common situations: Typo in config (max_passes: 0); user setting an unbounded pass count; version change where MAX_REVIEW_PASSES was lowered below a stored config value.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Review max_chars must be positive
- --attempts must be an integer from 1 to 20
- --channel, --version and --reason are required
- Choose one Runtime --thread ID.
- click supports left with 1-3 clicks, right x1 or middle x1
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/92349599a6f7894e.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tools/review.rs:432
},
}
/// Plan PR review passes over `diff`, degrading instead of failing closed
/// (#6285 AC3): files that fit no pass and passes beyond `max_passes` are
/// skipped in diff order and named in `manifest.skipped_files` (AC4). Only a
/// plan that covers nothing still errors.
///
/// Known limitations, beside the behaviour: skips are whole files — a file
/// with one oversized hunk is skipped entirely, never truncated — and files
/// stay in diff order rather than re-sorted by estimated risk.
pub(crate) fn plan_pr_review(
diff: &str,
view: &super::review_pr::GhPullRequest,
max_chars: usize,
max_passes: usize,
) -> anyhow::Result<PrReviewPlan> {
anyhow::ensure!(max_chars > 0, "Review max_chars must be positive");
anyhow::ensure!(
(1..=MAX_REVIEW_PASSES).contains(&max_passes),
"Review max_passes must be from 1 to {MAX_REVIEW_PASSES}"
);
let patches = pr_file_patches(diff);
anyhow::ensure!(
patches.len() == view.changed_files && !patches.is_empty(),
"Complete PR review plan found {} file patches; expected {}",
patches.len(),
view.changed_files
);
// A whole file stays together whenever it fits. An oversized text file
// splits only at complete hunk boundaries, with the full file header
// replayed into every part so each part stays a self-describing patch;
// no line is elided, shortened or reordered. Sizes use the model
// representation, so a binary payload already omitted there can never
// drive a split.
let mut atoms: Vec<PrReviewAtom<'_>> = Vec::new();View on GitHub (pinned to 73e0f67d83)