zed-industries/zed · error
custom server error: {} - {}
Error message
custom server error: {} - {} What it means
OpenAI-compatible provider client used for user-configured custom LLM servers: any non-2xx completion response reads the body and bails as `custom server error: {status} - {body}` (open_ai_compatible.rs:117). Because the server is arbitrary, the body may be a provider JSON error or a plain HTML error page — both are surfaced verbatim.
Source
Thrown at crates/edit_prediction/src/open_ai_compatible.rs:117
.method(http_client::Method::POST)
.uri(settings.api_url.as_ref())
.header("Content-Type", "application/json");
if let Some(api_key) = api_key {
http_request_builder =
http_request_builder.header("Authorization", format!("Bearer {}", api_key));
}
let http_request =
http_request_builder.body(http_client::AsyncBody::from(request_body))?;
let mut response = http_client.send(http_request).await?;
let status = response.status();
if !status.is_success() {
let mut body = String::new();
response.body_mut().read_to_string(&mut body).await?;
anyhow::bail!("custom server error: {} - {}", status, body);
}
let mut body = String::new();
response.body_mut().read_to_string(&mut body).await?;
let parsed: RawCompletionResponse =
serde_json::from_str(&body).context("Failed to parse completion response")?;
let text = parsed
.choices
.into_iter()
.next()
.map(|choice| choice.text)
.unwrap_or_default();
Ok((text, parsed.id))
}
}
}
View on GitHub (pinned to f4178619ac)
Solutions
- Reproduce with curl against the same URL, key, and model to see the raw server response.
- Fix the base URL to include the versioned prefix (e.g. `http://localhost:11434/v1`) and use the chat-completions path the server implements.
- Confirm the API key header the server expects (Bearer vs custom) and that the model id exists on that server.
- For 5xx HTML bodies, fix the gateway/reverse-proxy in front of the model server.
Example fix
// before (Zed settings — wrong api_url, server answers 404) "api_url": "http://localhost:11434" // after (OpenAI-compatible base path) "api_url": "http://localhost:11434/v1"
Defensive patterns
Strategy: validation
Validate before calling
# smoke-test the custom server exactly as Zed will call it
curl -sS "$ZED_API_URL/chat/completions" \
-H "Authorization: Bearer $ZED_API_KEY" -H 'Content-Type: application/json' \
-d '{"model":"'$ZED_MODEL'","messages":[{"role":"user","content":"ping"}]}' \
|| echo "fix api_url (must include /v1), key, or model before use" Type guard
fn looks_like_openai_base_url(url: &str) -> bool {
let path = url.split_once("://").map(|(_, rest)| rest).unwrap_or(url);
!path.is_empty() && !url.contains(' ') && (path.ends_with("/v1") || path.split('/').count() >= 2)
} Try / catch
Catch the bail and parse `{status} - {body}`: for 404 print a hint about the missing `/v1` prefix, for 401 about the API key, for HTML bodies about the reverse proxy; only retry on 5xx/429. Prevention
- Always include the versioned base path (`/v1`) in api_url.
- Verify the model id exists on the server with curl before configuring Zed.
- Confirm the server actually implements the OpenAI chat-completions schema, not merely a similar one.
When it happens
Trigger: A custom server completion request returning 401 (bad API key), 404 (base URL missing `/v1` or wrong path), 400 (model/chat/completions not supported), 429, or an HTML 502 from a gateway in front of the model server.
Common situations: Pointing Zed at Ollama/LM Studio/vLLM/LiteLLM with a wrong `api_url` (missing `/v1`), a model id the server does not host, an expired key, or a local server that is not actually OpenAI-compatible.
Related errors
- Failed to connect to DeepSeek API: {} {}
- Failed to connect to Mistral API: {} {}
- Bedrock does not support custom tools
- could not locate run '{run_id}' in the local run index ({run
- missing Content-Type header
AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20).
Data as JSON: /api/errors/f393758601ffa745.
Report an issue: GitHub.