Hmbown/CodeWhale · error · anyhow::Error

Model response incomplete: provider stop reason

Error message

Model response incomplete: provider stop reason `{}`; the partial response was printed but the command did not succeed.

What it means

In the one-shot text output path, after printing the model's response blocks, the stop reason returned by the provider is checked with `is_incomplete_stop_reason`; if the response was cut short (e.g. max tokens, length), the command bails so scripts treat it as failed even though partial text was printed.

Solutions

  1. Increase the max output tokens / output budget for the request.
  2. Shorten the task or split it into multiple requests to fit the limit.
  3. Inspect the reported stop reason in the message to confirm the cause and adjust request parameters accordingly.

Example fix

// before
codewhale ask --model k3 --max-output-tokens 256 --prompt "...long task..."
// after
codewhale ask --model k3 --max-output-tokens 8192 --prompt "...long task..."
Defensive patterns

Strategy: try-catch

Try / catch

match run_one_shot_text(args) {
    Err(e) if e.to_string().contains("Model response incomplete") => {
        // partial output already printed; raise token budget or split task and retry
    }
    other => other?,
}

Prevention

When it happens

Trigger: A one-shot model request completes HTTP-wise but the provider reports an incomplete stop reason (such as max_tokens/length) in the text-printing code path.

Common situations: Long generations hitting the provider's max-output-token limit, truncation from a small configured output budget, or provider-side cutoffs.

Related errors


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

Appendix: source

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

        metadata: None,
        thinking: None,
        reasoning_effort,
        stream: Some(false),
        temperature: None,
        top_p: None,
    };

    let response = client.create_message(request).await?;
    let stop_reason = response.stop_reason.clone();

    for block in response.content {
        if let ContentBlock::Text { text, .. } = block {
            println!("{text}");
        }
    }

    if is_incomplete_stop_reason(stop_reason.as_deref()) {
        anyhow::bail!(
            "Model response incomplete: provider stop reason `{}`; the partial response was printed but the command did not succeed.",
            stop_reason_detail(stop_reason.as_deref())
        );
    }

    Ok(())
}

async fn run_one_shot_json(
    config: &Config,
    model: &str,
    prompt: &str,
    force_configured_route: bool,
) -> Result<()> {
    use crate::client::CodewhaleClient;
    use codewhale_models::{
        ContentBlock, Message, MessageRequest, SystemPrompt, is_incomplete_stop_reason,
        stop_reason_detail,

View on GitHub (pinned to 73e0f67d83)