chroma-core/chroma · error · ChromaServerError
${response.status}: ${response.statusText}
Error message
${response.status}: ${response.statusText} What it means
Thrown by chromaFetch (chroma-fetch.ts:142) as a ChromaServerError for any non-OK status not handled by the 400/401/403/404/409/412/422/429 switch — in practice HTTP 5xx. The message comes from getErrorMessage(): the body's message or error field if present, else the raw `${status}: ${statusText}` fallback, which is what you see when the error body is empty or not JSON (e.g. a 502/504 HTML page from a proxy).
Source
Thrown at clients/new-js/packages/chromadb/src/chroma-fetch.ts:142
) {
throw error;
}
throw new ChromaClientError(
`Unprocessable Entity: ${response.statusText}`,
);
}
case 429:
const rateLimitBody = await getErrorBody(response);
if (rateLimitBody.error === "Backoff") {
throw new ChromaBackoffError(
rateLimitBody.message || "Backoff and retry",
);
}
throw new ChromaRateLimitError("Rate limit exceeded");
}
const errorMessage = await getErrorMessage(response);
throw new ChromaServerError(errorMessage);
};
View on GitHub (pinned to aecdd12c8a)
Solutions
- Check Chroma server health/logs (docker logs, pod events) for the root cause of the 5xx.
- Retry with exponential backoff — 5xx and gateway errors are usually transient, especially 502/503/504.
- If '504'-style timeouts repeat under load, reduce batch sizes or scale the server (more replicas/CPU/memory).
- Verify client/server version compatibility if a deterministic 500 occurs on a specific call.
Example fix
// before
await collection.query({ queryTexts: ["x"] }); // occasional 502/504 from gateway
// after
async function withRetry<T>(fn: () => Promise<T>, tries = 5): Promise<T> {
for (let i = 0; ; i++) {
try { return await fn(); }
catch (e) {
if (e instanceof ChromaServerError && i < tries - 1) {
await new Promise(r => setTimeout(r, 2 ** i * 250 + Math.random() * 250));
continue;
}
throw e;
}
}
}
await withRetry(() => collection.query({ queryTexts: ["x"] })); Defensive patterns
Strategy: retry
Validate before calling
async function healthy(url: string): Promise<boolean> {
try { return (await fetch(`${url}/api/v2/heartbeat`)).ok; } catch { return false; }
} Try / catch
for (let attempt = 0; ; attempt++) {
try {
return await operation();
} catch (e) {
const transient = e instanceof ChromaServerError && !/\b5[0-9]{2}\b.*[Pp]anic/.test(e.message);
if (transient && attempt < 5) {
await new Promise(r => setTimeout(r, 2 ** attempt * 250 + Math.random() * 250));
continue;
}
throw e;
}
} Prevention
- Wrap all Chroma calls in exponential-backoff retry for 5xx/gateway errors.
- Monitor server health (heartbeat + container logs) so transient 5xx are explained.
- Right-size batches and server resources to avoid overload-induced 504/503.
When it happens
Trigger: Chroma server crashes (500), unhandled server bugs, maintenance restarts, or infrastructure-layer 502/503/504 from load balancers and proxies in front of Chroma when the upstream is down or timing out.
Common situations: Long ingestion jobs hitting a server OOM/restart; Kubernetes pod recycling while clients are connected; nginx returning '504: Gateway Time-out' when chroma is overloaded; version-skew server panics on new payloads.
Related errors
- conditional write conflict
- stale read
- Unprocessable Entity: ${response.statusText}
- Backoff and retry
- Rate limit exceeded
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/1fde029a19d67336.
Report an issue: GitHub.