Hmbown/CodeWhale · error · anyhow::Error
translate: provider response did not contain text content
Error message
translate: provider response did not contain text content
What it means
For OpenAI-compatible (chat completions) translation endpoints, the client reads `choices[0].message.content`; an empty/whitespace-only content string is rejected with this error instead of returning an empty translation. It is the OpenAI-format counterpart of the Anthropic empty-text check.
Solutions
- Retry the translation; content-filter or transient empty replies often clear on retry.
- Rephrase or shorten the input text if a content filter is emptying the response.
- Use a different model for translation that returns plain text content.
- Verify the endpoint is an OpenAI-compatible chat-completions API and not a proxy altering the payload.
Defensive patterns
Strategy: try-catch
Try / catch
match result {
Err(e) if e.to_string().contains("did not contain text content") => {
log::warn!("empty translation content; retrying once");
result = translate(input).await;
}
r => r?,
} Prevention
- Retry once on empty content before failing.
- Avoid models that commonly return empty content (refusals, reasoning-only) for translation.
- Check content-filter policies on the input text if refusals recur.
When it happens
Trigger: Provider returns choices[0].message.content = "" or whitespace — e.g. the model refused, hit a content filter, or returned a reasoning-only response with empty content.
Common situations: Content-filter refusals on the input text; a reasoning model returning empty content; misconfigured endpoint behind a proxy that strips content.
Related errors
- translate: Anthropic Messages response did not contain text…
- Antigravity cloud-code stream ended without a text part
- Compaction summary response was unusable: no text was…
- Kimi returned an empty native web-search tool call list
- Model returned terminal stop reason
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/ecb6f12b5bb95755.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/client.rs:2900
.iter()
.any(|field| usage.contains_key(*field))
});
let usage = parse_usage(value.get("usage"));
let stop_reason = value["choices"][0]["finish_reason"].as_str();
let usage = (usage_reported && usage != Usage::default()).then_some(usage);
let translated = if codewhale_models::is_incomplete_stop_reason(stop_reason) {
Err(anyhow::anyhow!(
"translate: provider response incomplete ({})",
codewhale_models::stop_reason_detail(stop_reason)
))
} else {
value["choices"][0]["message"]["content"]
.as_str()
.ok_or_else(|| anyhow::anyhow!("translate: unexpected API response shape"))
.and_then(|translated| {
let translated = translated.trim().to_string();
if translated.is_empty() {
bail!("translate: provider response did not contain text content");
}
Ok(translated)
})
};
Ok(TranslationProviderResponse {
translated,
route,
usage,
})
}
/// Test adapter for asserting the translated text; production retains receipts.
#[cfg(test)]
async fn translate(&self, text: &str, model: &str, target_language: &str) -> Result<String> {
self.translate_with_usage(text, model, target_language)
.await?
.translatedView on GitHub (pinned to 73e0f67d83)