{"record":{"id":"c6093304699478cf","repo":"Hmbown/CodeWhale","slug":"failed-to-call-chat-completions-api-http-status-error-text","errorCode":null,"errorMessage":"Failed to call {} Chat Completions API: HTTP {status}: {error_text}","messagePattern":"Failed to call (.+?) Chat Completions API: HTTP (.+?): (.+?)","errorType":"http","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/client/chat.rs","lineNumber":1303,"sourceCode":"            None\n        };\n\n        // The endpoint was resolved by the shared seam alongside the body, so\n        // a route-shape decision (e.g. DeepSeek's strict-tools `/beta` path)\n        // cannot be made twice with two different answers.\n        let url = prepared.endpoint.url.as_str();\n        let response = self.send_json_with_retry(url, body).await?;\n\n        let status = response.status();\n        crate::client::record_provider_response(self.api_provider, status.as_u16());\n        if !status.is_success() {\n            let raw_error_text = bounded_error_text(response, ERROR_BODY_MAX_BYTES).await;\n            let error_text = sanitize_http_error_body(\n                Some(self.api_provider.display_name()),\n                status.as_u16(),\n                &raw_error_text,\n            );\n            anyhow::bail!(\n                \"Failed to call {} Chat Completions API: HTTP {status}: {error_text}\",\n                self.api_provider.display_name()\n            );\n        }\n\n        let response_text = response\n            .text()\n            .await\n            .context(\"Failed to read Chat API response body\")?;\n        let value: Value =\n            serde_json::from_str(&response_text).context(\"Failed to parse Chat API JSON\")?;\n        let parsed = parse_chat_message_for_route(&value, self.api_provider, &self.base_url)?;\n        if let Some(key) = response_cache_key {\n            crate::llm_response_cache::response_cache().put(key, parsed.clone());\n        }\n        Ok(parsed)\n    }\n}","sourceCodeStart":1285,"sourceCodeEnd":1321,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/client/chat.rs#L1285-L1321","documentation":"A non-streaming Chat Completions request returned a non-success HTTP status. The bounded error body is sanitized with the provider display name and re-raised with the status, so this is the generic surface for every upstream Chat Completions API error (auth, quota, bad request, model not found). Raised in `create_message_chat` in `crates/tui/src/client/chat.rs` around line 1303, reached via `create_message_with_cache_policy`.","triggerScenarios":"Any non-2xx from POST `{base_url}/chat/completions`: 401 invalid API key, 403 no model access, 404 unknown model, 429 rate limit, 400 invalid request body (bad messages/tools/payload), 5xx provider outage.","commonSituations":"Wrong or expired API keys; model names not available on the configured provider/plan; payloads exceeding context limits; provider-side incidents; misconfigured base URLs hitting a path that 404s.","solutions":["Read the sanitized provider `error_text` in the message and fix the named cause.","Verify API key and model access for `self.api_provider`.","For 429, add backoff/retry; for 5xx, retry later or switch provider.","For 400, validate the messages/tools payload (often context-length or schema issues)."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"fn chat_request_precheck(api_key: &str, model: &str, messages: &[Value]) -> Result<(), String> {\n    if api_key.trim().is_empty() { return Err(\"missing API key\".into()); }\n    if messages.is_empty() { return Err(\"empty messages\".into()); }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":"match client.create_message(req).await {\n    Err(e) if e.to_string().contains(\"Chat Completions API: HTTP\") => {\n        match extract_status(&e.to_string()) {\n            429 | 500..=599 => retry_with_backoff().await,\n            401 | 403 => Err(anyhow!(\"check provider key/model access: {e}\")),\n            _ => Err(e),\n        }\n    }\n    other => other,\n}","preventionTips":["Verify API key and model entitlement before non-stream calls.","Back off on 429 and provider 5xx.","Validate messages fit the model's context window.","Confirm the base URL resolves to the correct provider path."],"tags":["http","api","chat-completions"],"backgroundTag":"http-error-response","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"}