Hmbown/CodeWhale · error · anyhow::Error
translate: provider response incomplete
Error message
translate: provider response incomplete ({}) What it means
After receiving an Anthropic Messages (or Responses API) reply, the client checks the stop reason with codewhale_models::is_incomplete_stop_reason and errors out if the provider explicitly did not finish: output token limit (length/max_tokens), content_filter, model_context_window_exceeded, or any `incomplete:*` reason. Rather than returning a truncated translation as if it were complete, the client surfaces the provider's stop reason detail in the message.
Solutions
- Increase the max output tokens / output budget for the request so generation can finish
- Shrink the prompt or conversation history (compact context) to avoid context-window exhaustion
- Check whether a content filter applies and rephrase or switch model/provider
- Read the detail inside the message (stop_reason_detail) to identify which of length/content_filter/context-window caused it and address that specific cause
Example fix
// before request.max_tokens = 256; // generation truncated at limit // after request.max_tokens = 4096; // enough headroom for the full response
Defensive patterns
Strategy: retry
Validate before calling
// Before sending, check the request fits the output budget:
if request.max_tokens.unwrap_or(0) < 1024 {
eprintln!("max_tokens is low; Anthropic responses risk finishing with stop_reason=\"max_tokens\"");
}
Try / catch
match result {
Err(e) if e.to_string().starts_with("translate: provider response incomplete") => {
let detail = e.to_string(); // e.g. "max_tokens" / "content_filter"
if detail.contains("max_tokens") || detail.contains("length") {
// retry once with a larger output budget and compacted context
} else {
// surface to user: filter or context-window issue, do not blind-retry
}
}
other => other?,
}
Prevention
- Set generous output token budgets relative to expected answer length
- Compact conversation history before it approaches the model context window
- Never treat a partial response as final; check stop_reason in any raw Anthropic handling
- Subscribe to provider changelogs for new stop reasons; `incomplete:*` reasons are intentionally rejected
When it happens
Trigger: A request whose response carries stop_reason "length"/"max_tokens"/"max_output_tokens" (output cap hit), "content_filter", "model_context_window_exceeded", or an `incomplete:`-prefixed reason, on the Anthropic Messages path in the translate flow (client.rs:2815).
Common situations: Low max_tokens / output budget configured while the model needs more tokens; a provider safety filter truncating output; the conversation exceeding the model context window so generation stops early; a provider introducing a new incomplete stop reason spelled `incomplete:<future-reason>`.
Related errors
- Anthropic API error (HTTP )
- Anthropic stream error
- Compaction summary response incomplete: provider stop reason
- API key not found. Run 'codewhale auth set --provider '…
- At least one thread field is required
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/edb093fa6d2d8590.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/client.rs:2815
// Non-Chat dialects reuse the prepared-request seam so translation
// cannot drift from production shaping. Translation is still an
// *auxiliary* call, not a primary agent turn: the Chat dialect
// below builds its own small fixed body, and `/preview-request`
// deliberately does not claim to describe either
// (see `docs/PREVIEW_REQUEST.md`).
let prepared = self.prepare_outbound_request(
translation_message_request(text, model, target_language, max_tokens),
false,
)?;
let response = match prepared.dialect {
WireDialect::OpenAiResponses => self.handle_responses_message(&prepared).await?,
WireDialect::AnthropicMessages => self.handle_anthropic_message(&prepared).await?,
WireDialect::ChatCompletions => unreachable!(),
};
let usage = (response.usage != Usage::default()).then_some(response.usage.clone());
let translated =
if codewhale_models::is_incomplete_stop_reason(response.stop_reason.as_deref()) {
Err(anyhow::anyhow!(
"translate: provider response incomplete ({})",
codewhale_models::stop_reason_detail(response.stop_reason.as_deref())
))
} else {
translation_text_from_response(&response)
};
return Ok(TranslationProviderResponse {
translated,
route,
usage,
});
}
let url = api_url_with_suffix(
self.chat_transport_base_url(),
"chat/completions",
self.path_suffix.as_deref(),
);View on GitHub (pinned to 73e0f67d83)