{"record":{"id":"ecb6f12b5bb95755","repo":"Hmbown/CodeWhale","slug":"translate-provider-response-did-not-contain-text-content","errorCode":null,"errorMessage":"translate: provider response did not contain text content","messagePattern":"translate: provider response did not contain text content","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/client.rs","lineNumber":2900,"sourceCode":"                .iter()\n                .any(|field| usage.contains_key(*field))\n            });\n        let usage = parse_usage(value.get(\"usage\"));\n        let stop_reason = value[\"choices\"][0][\"finish_reason\"].as_str();\n        let usage = (usage_reported && usage != Usage::default()).then_some(usage);\n        let translated = if codewhale_models::is_incomplete_stop_reason(stop_reason) {\n            Err(anyhow::anyhow!(\n                \"translate: provider response incomplete ({})\",\n                codewhale_models::stop_reason_detail(stop_reason)\n            ))\n        } else {\n            value[\"choices\"][0][\"message\"][\"content\"]\n                .as_str()\n                .ok_or_else(|| anyhow::anyhow!(\"translate: unexpected API response shape\"))\n                .and_then(|translated| {\n                    let translated = translated.trim().to_string();\n                    if translated.is_empty() {\n                        bail!(\"translate: provider response did not contain text content\");\n                    }\n                    Ok(translated)\n                })\n        };\n\n        Ok(TranslationProviderResponse {\n            translated,\n            route,\n            usage,\n        })\n    }\n\n    /// Test adapter for asserting the translated text; production retains receipts.\n    #[cfg(test)]\n    async fn translate(&self, text: &str, model: &str, target_language: &str) -> Result<String> {\n        self.translate_with_usage(text, model, target_language)\n            .await?\n            .translated","sourceCodeStart":2882,"sourceCodeEnd":2918,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/client.rs#L2882-L2918","documentation":"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.","triggerScenarios":"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.","commonSituations":"Content-filter refusals on the input text; a reasoning model returning empty content; misconfigured endpoint behind a proxy that strips content.","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."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"did not contain text content\") => {\n        log::warn!(\"empty translation content; retrying once\");\n        result = translate(input).await;\n    }\n    r => r?,\n}","preventionTips":["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."],"tags":["openai","translation","empty-response","api-response"],"backgroundTag":"empty-response-body","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}