Hmbown/CodeWhale · error · anyhow::Error
FIM API error: HTTP
Error message
FIM API error: HTTP {status}: {error_text} What it means
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.
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.
Defensive patterns
Strategy: try-catch
Validate before calling
// Probe availability once at startup
let probe = client.fim_completion(test_req.clone()).await;
let fim_available = !probe.as_ref().map_err(|e| e.to_string()).err().map_or(false, |s| s.contains("HTTP 404")); Try / catch
match client.fim_completion(req).await {
Err(e) if e.to_string().contains("FIM API error: HTTP") => {
if extract_status(&e.to_string()) == 429 { retry_with_backoff(); }
else { disable_fim_for_session(); }
}
other => other,
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- ${compactRuntimeError(response.status, result)}
- DeepSeek
- detail || ("HTTP " + res.status)
- iLink API failed: HTTP
- Speech synthesis failed: HTTP
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/6865824179a3bf86.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/client.rs:5133
let url = api_url_with_suffix(&self.base_url, "beta/completions", None);
let model = self.wire_model_for_route(model);
let max_tokens = max_tokens.min(self.effective_max_output_tokens(&model));
let body = json!({
"model": model,
"prompt": prompt,
"suffix": suffix,
"max_tokens": max_tokens,
});
let response = self.send_json_with_retry(&url, &body).await?;
let status = response.status();
if !status.is_success() {
let raw_error_text = bounded_error_text(response, ERROR_BODY_MAX_BYTES).await;
let error_text = sanitize_http_error_body(
Some(self.api_provider.display_name()),
status.as_u16(),
&raw_error_text,
);
anyhow::bail!("FIM API error: HTTP {status}: {error_text}");
}
let response_text = response
.text()
.await
.context("Failed to read FIM API response body")?;
let value: serde_json::Value =
serde_json::from_str(&response_text).context("Failed to parse FIM API response")?;
let text = value
.pointer("/choices/0/text")
.and_then(serde_json::Value::as_str)
.ok_or_else(|| anyhow::anyhow!("FIM response missing choices[0].text"))?;
Ok(text.to_string())
}
}
mod anthropic;
mod chat;
mod deepseek_effort;View on GitHub (pinned to 73e0f67d83)