Hmbown/CodeWhale · error

FIM API error: HTTP {status}: {error_text}

Error message

FIM API error: HTTP {status}: {error_text}

What it means

`fim_completion` (the fill-in-the-middle autocomplete backing the FIM tool) posts `{model, prompt, suffix, max_tokens}` to `{base_url}/beta/completions` — DeepSeek's FIM endpoint — and bails on any non-2xx status after the retrying transport gives up. Earlier guards already rejected non-chat-completions wire formats and the OpencodeZen provider, so this error means the endpoint answered but with an error status; the body (64KB cap) is sanitized with the provider display name before inclusion.

Source

Thrown at crates/tui/src/client.rs:3631

        }
        let url = api_url_with_suffix(&self.base_url, "beta/completions", None);
        let model = wire_model_for_provider_route(self.api_provider, &self.base_url, 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;
pub(crate) mod cloud_code;

View on GitHub (pinned to 8880682c63)

Solutions

  1. Point the FIM tool's provider/base_url at a server that implements DeepSeek's `/beta/completions` FIM surface and use a FIM-capable model.
  2. Check the status in the message: 401 → fix the key; 404 → the endpoint does not exist on this base_url; 400 → wrong model for FIM.
  3. Verify with curl: `curl -s $BASE_URL/beta/completions -H "Authorization: Bearer $KEY" -d '{"model":"<fim-model>","prompt":"a","suffix":"b","max_tokens":8}'`.
  4. If the provider cannot serve FIM, disable the FIM tool rather than letting every keystroke trigger this error.

Example fix

# before
[fim]
model = "deepseek-chat"
# after
[fim]
model = "deepseek-coder"   # FIM-capable model served by /beta/completions
Defensive patterns

Strategy: try-catch

Validate before calling

// Preflight the FIM endpoint once before enabling autocomplete.
async fn fim_endpoint_ok(base_url: &str, key: &str, model: &str) -> bool {
    let url = format!("{base_url}/beta/completions");
    reqwest::Client::new().post(&url).bearer_auth(key)
        .json(&serde_json::json!({"model": model, "prompt": "a", "suffix": "b", "max_tokens": 4}))
        .send().await.is_ok_and(|r| r.status().is_success())
}

Type guard

fn fim_supported(provider: ApiProvider, wire: WireFormat) -> bool {
    provider != ApiProvider::OpencodeZen && wire == WireFormat::ChatCompletions
}

Try / catch

match client.fim_completion(&model, prompt, suffix, max_tokens).await {
    Ok(text) => render_completion(text),
    Err(e) if e.to_string().contains("FIM API error: HTTP 404") => disable_fim_tool("endpoint has no /beta/completions"),
    Err(e) if e.to_string().contains("HTTP 401") => prompt_for_api_key(),
    Err(e) => log_and_suppress(e), // never block typing on an autocomplete failure
}

Prevention

When it happens

Trigger: 401/403 wrong API key; 404 when the base_url's server does not implement `/beta/completions` (OpenAI, most OpenAI-compatible proxies); 400 when the model id is a chat model without FIM support; 429/5xx rate limits and outages.

Common situations: Enabling the FIM autocomplete tool while pointed at a generic OpenAI-compatible gateway that only implements `/chat/completions`; using `deepseek-chat` instead of a FIM-capable model; stale API key; base_url missing or doubling the `/v1` prefix so `/v1/beta/completions` does not resolve.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/6865824179a3bf86. Report an issue: GitHub.