Hmbown/CodeWhale · error · anyhow::Error

; publication: ; completed review passes: / ; accumulated…

Error message

{message}; publication: {publication}; completed review passes: {completed_passes}/{planned_passes}; accumulated usage: {usage}

What it means

Terminal bail for a failed PR review run: it wraps the underlying failure message and appends the publication mode, how many of the planned review passes completed, and the accumulated token usage serialized as JSON. It exists so a failed multi-pass review still reports progress and cost context in one message.

Solutions

  1. Read the leading `{message}` segment for the root cause and fix that underlying error
  2. Check completed passes vs planned; re-run with a higher --max-passes if the run was cut short
  3. Inspect the accumulated usage JSON to check whether token/char limits contributed to the failure
Defensive patterns

Strategy: try-catch

Try / catch

// the bail appends progress/usage to the root cause; parse the leading message for the real error
let err = run_review().await.unwrap_err();
let root = err.to_string().split("; publication:").next().unwrap_or("");
eprintln!("review failed: {root}");

Prevention

When it happens

Trigger: Any failure during a `codewhale review` run after passes have started: the underlying error `message` is caught, then this bail re-raises it with publication status, completed_passes/planned_passes, and usage JSON appended.

Common situations: A review pass fails mid-run (API error, provider failure); diagnosing how far a multi-pass review got and how much budget it consumed before failing.

Related errors


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

Appendix: source

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

) -> Result<()> {
    let message = message.into();
    if args.json {
        println!(
            "{}",
            serde_json::to_string_pretty(&review_failure_payload(
                provider,
                model,
                usage,
                completed_passes,
                planned_passes,
                publication,
                &message,
            ))?
        );
    }
    let usage = serde_json::to_string(usage)?;
    let publication = publication.as_str();
    bail!(
        "{message}; publication: {publication}; completed review passes: {completed_passes}/{planned_passes}; accumulated usage: {usage}"
    )
}

/// Apply `codewhale review --provider <name>` and decide whether the route is
/// authoritative (no cross-provider inventory inference).
///
/// This mirrors `codewhale exec --provider` (#4093): the flag sets ONLY the
/// non-secret provider identity, and pinning the route is what lets a model
/// offered by more than one configured route resolve instead of hard-erroring
/// in `resolve_cli_auto_route`.
fn review_execution_route(config: &Config, args: &ReviewArgs) -> Result<(Config, bool)> {
    let explicit_provider = non_empty_flag(args.provider.as_deref());
    let explicit_model = non_empty_flag(args.model.as_deref());
    let mut resolved = config.clone();
    if let Some(provider_arg) = explicit_provider {
        apply_exec_provider_override(&mut resolved, provider_arg)?;
    }

View on GitHub (pinned to 73e0f67d83)