chroma-core/chroma · error · ChromaClientError
Precondition Failed
Error message
Precondition Failed
What it means
Thrown by chromaFetch (chroma-fetch.ts:105) as a generic ChromaClientError when the server returns 412 but the body is not a StaleReadError. HTTP 412 means a precondition the client asserted in request headers (e.g. If-Match / version-match style checks) failed: the resource state does not satisfy the condition the client demanded.
Source
Thrown at clients/new-js/packages/chromadb/src/chroma-fetch.ts:105
if (
conflictBody.error === "ConditionalWriteConflictError" ||
conflictBody.message === "conditional write conflict"
) {
throw new ChromaConditionalWriteConflictError(
conflictBody.message || "conditional write conflict",
);
}
throw new ChromaUniqueError(
conflictBody.message || "The resource already exists",
);
case 412:
const preconditionBody = await getErrorBody(response);
if (preconditionBody.error === "StaleReadError") {
throw new ChromaStaleReadError(
preconditionBody.message || "stale read",
);
}
throw new ChromaClientError(
preconditionBody.message || "Precondition Failed",
);
case 422:
try {
const body = await response.json();
if (
body &&
body.message &&
(body.message.startsWith("Quota exceeded") ||
body.message.startsWith("Billing limit exceeded"))
) {
throw new ChromaQuotaExceededError(body?.message);
}
throw new ChromaClientError(body?.message || "Unprocessable Entity");
} catch (error) {
if (
error instanceof ChromaQuotaExceededError ||
error instanceof ChromaClientErrorView on GitHub (pinned to aecdd12c8a)
Solutions
- Inspect the server's message in the error body to identify which precondition failed.
- Re-read the current resource state/version and reissue the request with a fresh precondition or none.
- If a proxy injects precondition headers, remove or fix that configuration.
- Wrap the call in a retry loop that refreshes the version on each 412.
Example fix
// before
await collection.delete({ ids }, /* ifVersion */ staleVersion); // 412 Precondition Failed
// after
const current = await client.getCollection({ name: collection.name }); // refresh version
await current.delete({ ids }); // or pass current.version as the precondition Defensive patterns
Strategy: retry
Try / catch
try {
await collection.delete(args);
} catch (e) {
if (e instanceof ChromaClientError && /Precondition/.test(e.message)) {
// re-read current version, then re-issue with fresh precondition or without one
}
throw e;
} Prevention
- Keep preconditions short-lived: read the version immediately before the guarded write.
- Refresh resource state after any 412 before retrying.
- Only attach version preconditions when you actually need lost-update detection.
When it happens
Trigger: A request with a version/precondition header whose expectation no longer holds — e.g. delete or update with if-version equal to an outdated collection version, or gateway-injected precondition checks failing.
Common situations: Optimistic version checks on collection modifications racing with other writers; proxies/load balancers adding If-* header checks; custom server middleware enforcing preconditions.
Related errors
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/d28cb2c1a6ff4df2.
Report an issue: GitHub.