chroma-core/chroma · error
got empty embedding at pos
Error message
got empty embedding at pos
What it means
Thrown client-side by prepareRecordRequest when the embeddings array that will be sent contains at least one empty vector (length 0). Chroma cannot store a zero-dimensional embedding, and an empty vector almost always means the embedding function produced no output for that input or a placeholder [] slipped into your data. The check runs on both user-supplied embeddings and embeddings generated by the embedding function.
Source
Thrown at clients/js/packages/chromadb-core/src/utils.ts:162
"ids, embeddings, metadatas, and documents must all be the same length",
);
}
const uniqueIds = new Set(ids);
if (uniqueIds.size !== ids.length) {
const duplicateIds = ids.filter(
(item, index) => ids.indexOf(item) !== index,
);
throw new Error(
`ID's must be unique, found duplicates for: ${duplicateIds}`,
);
}
if (
embeddingsArray &&
embeddingsArray.some((embedding) => embedding.length === 0)
) {
throw new Error("got empty embedding at pos");
}
return {
ids,
metadatas,
documents,
embeddings: embeddingsArray,
};
}
export function wrapCollection(
api: ChromaClient,
collection: CollectionParams,
): Collection {
return new Collection(
collection.name,
collection.id,
api,View on GitHub (pinned to aecdd12c8a)
Solutions
- Find the empty vector position before sending: embeddings.findIndex(e => e.length === 0), then fix or remove that record.
- Filter out empty/blank documents before calling add() so the embedding function never receives them.
- If a custom embedding function returns [] on failure, make it throw instead, or drop the failed record from the batch.
- Verify the embedding model's dimension is applied to every vector (e.g., truncated PCA output or slicing bugs).
Example fix
// before
await collection.add({
ids: ["1", "2"],
documents: ["hello", ""], // empty doc -> empty embedding
});
// after
const keep = documents.map((d, i) => [d, i]).filter(([d]) => d.trim() !== "");
await collection.add({
ids: keep.map(([, i]) => ids[i]),
documents: keep.map(([d]) => d),
}); Defensive patterns
Strategy: validation
Validate before calling
function hasEmptyEmbedding(embeddings: number[][]): boolean {
return embeddings.some((e) => !Array.isArray(e) || e.length === 0);
}
const badIndex = embeddings.findIndex((e) => e.length === 0);
if (badIndex !== -1) {
throw new Error(`Record at index ${badIndex} has an empty embedding; fix or drop it`);
}
await collection.add({ ids, embeddings }); Type guard
function isNonEmptyEmbeddings(e: unknown): e is number[][] {
return (
Array.isArray(e) &&
e.length > 0 &&
e.every((v) => Array.isArray(v) && v.length > 0 && v.every((n) => typeof n === "number"))
);
} Prevention
- Filter blank/empty documents before add() so the embedding function never sees them.
- Make custom embedding functions throw on failure instead of returning [].
- Validate every vector has the expected dimension before batching.
- Log the index of the first empty vector when pre-checking large batches.
When it happens
Trigger: Passing embeddings: [[0.1, 0.2], [], [0.3, 0.4]] to collection.add()/upsert(); an embedding function that returns [] for empty-string documents; a pre-processing step that maps failed embeds to [] instead of dropping them; mismatched slicing of an embeddings array that yields empty rows.
Common situations: Batching documents where some are empty strings after cleaning; partial API failures from a custom embedding function filled with [] placeholders; CSV rows with missing text mapped to empty embeddings; dimensions array misconfigured so some vectors get truncated to nothing.
Related errors
- The model name cannot be changed after initialization.
- The task type cannot be changed after initialization.
- Changing the URL is not allowed.
- Cannot change model name.
- embeddings and documents cannot both be undefined
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/15ad82f01f8f166e.
Report an issue: GitHub.