chroma-core/chroma · error · ChromaClientError
Unprocessable Entity
Error message
Unprocessable Entity
What it means
Thrown by chromaFetch (chroma-fetch.ts:119) as a ChromaClientError when the server returns 422, the JSON body parses, but it carries no usable `message` field and none of the quota/billing prefixes match. The server rejected the request as semantically invalid (well-formed but unacceptable content), and the library falls back to the bare status text.
Source
Thrown at clients/new-js/packages/chromadb/src/chroma-fetch.ts:119
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 ChromaClientError
) {
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",
);
}View on GitHub (pinned to aecdd12c8a)
Solutions
- Inspect the raw response by reproducing the request with curl to see the server's full 422 body.
- Align client and server versions so error payloads and API contracts match.
- Validate payload invariants client-side (equal-length ids/documents/embeddings/metadata arrays, valid metadata value types).
- Check the collection's embedding configuration against the data you send.
Example fix
// before
await collection.add({ ids: ["1", "2"], documents: ["only-one"] }); // length mismatch => 422
// after
await collection.add({ ids: ["1", "2"], documents: ["first", "second"] }); Defensive patterns
Strategy: validation
Validate before calling
function assertBatchShape(b: { ids: string[]; documents?: string[]; embeddings?: number[][]; metadatas?: object[] }) {
const n = b.ids.length;
if (b.documents && b.documents.length !== n) throw new Error("documents length mismatch");
if (b.embeddings && b.embeddings.length !== n) throw new Error("embeddings length mismatch");
if (b.metadatas && b.metadatas.length !== n) throw new Error("metadatas length mismatch");
} Try / catch
try {
await collection.add(batch);
} catch (e) {
if (e instanceof ChromaClientError && e.message === "Unprocessable Entity") {
// server gave no message: reproduce with curl to read the raw 422 body
}
throw e;
} Prevention
- Validate array-length and type invariants client-side before every add/upsert.
- Keep client/server versions aligned so 422 bodies carry actionable messages.
- Log the raw response body in debug wrappers when the library's message is bare.
When it happens
Trigger: Semantic validation failures server-side: invalid embedding function configuration, malformed metadata values, inconsistent document/embedding array lengths, or any 422 whose error body uses a different shape than {message}.
Common situations: Version skew where an older server emits differently shaped 422 bodies; hand-built payloads skipping required fields; custom server middleware returning 422 without a message.
Related errors
- Bad request to ${(input as Request).url || "Chroma"} with st
- Cannot specify both 'hnsw' and 'spann' configurations during
- Invalid HNSW config provided in CreateCollectionConfiguratio
- Invalid SPANN config provided in CreateCollectionConfigurati
- Cannot specify both 'hnsw' and 'spann' configurations during
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/67b09c4d4d613c56.
Report an issue: GitHub.