{"record":{"id":"6865824179a3bf86","repo":"Hmbown/CodeWhale","slug":"fim-api-error-http-status-error-text","errorCode":null,"errorMessage":"FIM API error: HTTP {status}: {error_text}","messagePattern":"FIM API error: HTTP (.+?): (.+?)","errorType":"http","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/client.rs","lineNumber":5133,"sourceCode":"        let url = api_url_with_suffix(&self.base_url, \"beta/completions\", None);\n        let model = self.wire_model_for_route(model);\n        let max_tokens = max_tokens.min(self.effective_max_output_tokens(&model));\n        let body = json!({\n            \"model\": model,\n            \"prompt\": prompt,\n            \"suffix\": suffix,\n            \"max_tokens\": max_tokens,\n        });\n        let response = self.send_json_with_retry(&url, &body).await?;\n        let status = response.status();\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!(\"FIM API error: HTTP {status}: {error_text}\");\n        }\n        let response_text = response\n            .text()\n            .await\n            .context(\"Failed to read FIM API response body\")?;\n        let value: serde_json::Value =\n            serde_json::from_str(&response_text).context(\"Failed to parse FIM API response\")?;\n        let text = value\n            .pointer(\"/choices/0/text\")\n            .and_then(serde_json::Value::as_str)\n            .ok_or_else(|| anyhow::anyhow!(\"FIM response missing choices[0].text\"))?;\n        Ok(text.to_string())\n    }\n}\n\nmod anthropic;\nmod chat;\nmod deepseek_effort;","sourceCodeStart":5115,"sourceCodeEnd":5151,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/client.rs#L5115-L5151","documentation":"The FIM (`beta/completions`) HTTP request returned a non-success status. The error body is read with a byte bound, sanitized with provider attribution via `sanitize_http_error_body`, and re-raised with the HTTP status so the upstream cause is directly visible. Raised in `crates/tui/src/client.rs` around line 5133.","triggerScenarios":"Any non-2xx response from POST `{base_url}/beta/completions`: unknown/undiscovered `beta/completions` path (404), bad model id, auth failure, quota exhaustion, malformed prompt/suffix payload.","commonSituations":"Provider endpoints that do not actually expose `beta/completions` (404); wrong base URL configured so the path 404s; API keys without FIM/beta access; rate limits during heavy autocomplete traffic.","solutions":["Read the sanitized `error_text` — it names the provider-side cause.","Confirm the base URL + provider actually exposes `beta/completions` (a 404 here means no FIM route).","Check API key validity and quota if status is 401/403/429.","Validate the prompt/suffix and model id in the FIM request."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Probe availability once at startup\nlet probe = client.fim_completion(test_req.clone()).await;\nlet fim_available = !probe.as_ref().map_err(|e| e.to_string()).err().map_or(false, |s| s.contains(\"HTTP 404\"));","typeGuard":null,"tryCatchPattern":"match client.fim_completion(req).await {\n    Err(e) if e.to_string().contains(\"FIM API error: HTTP\") => {\n        if extract_status(&e.to_string()) == 429 { retry_with_backoff(); }\n        else { disable_fim_for_session(); }\n    }\n    other => other,\n}","preventionTips":["Confirm the provider endpoint actually exposes beta/completions (404 = no FIM).","Back off on 429; autocomplete bursts easily hit rate limits.","Validate API key scope includes beta endpoints."],"tags":["http","network","api","fim"],"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"}