chroma-core/chroma · error
embeddings and documents cannot both be undefined
Error message
embeddings and documents cannot both be undefined
What it means
prepareRecordRequest() is used by Collection.add() and Collection.upsert() (the update flag is not set for those). If the request provides neither `embeddings` nor `documents`, there is nothing to embed or store as text, so it rejects before any network call. Attaching an embedding function to the collection does not help — the function needs documents as input.
Source
Thrown at clients/js/packages/chromadb-core/src/utils.ts:117
embeddings: params.embeddings
? toArrayOfArrays(params.embeddings)
: undefined,
metadatas: params.metadatas
? toArray<Metadata>(params.metadatas)
: undefined,
documents: params.documents ? toArray(params.documents) : undefined,
};
}
export async function prepareRecordRequest(
reqParams: AddRecordsParams | UpdateRecordsParams,
embeddingFunction: IEmbeddingFunction,
update?: true,
): Promise<MultiRecordOperationParams> {
const { ids, embeddings, metadatas, documents } = arrayifyParams(reqParams);
if (!embeddings && !documents && !update) {
throw new Error("embeddings and documents cannot both be undefined");
}
const embeddingsArray = embeddings
? embeddings
: documents
? await embeddingFunction.generate(documents)
: undefined;
if (!embeddingsArray && !update) {
throw new Error("Failed to generate embeddings for your request.");
}
for (let i = 0; i < ids.length; i += 1) {
if (typeof ids[i] !== "string") {
throw new Error(
`Expected ids to be strings, found ${typeof ids[i]} at index ${i}`,
);
}View on GitHub (pinned to aecdd12c8a)
Solutions
- Pass documents so the embedding function can generate vectors: collection.add({ ids, documents }).
- Or pass precomputed embeddings: collection.add({ ids, embeddings }) — one vector per id.
- If the intent was a metadata-only update of existing records, use collection.update({ ids, metadatas }), which permits omitting both.
Example fix
// before
await collection.add({ ids: ["doc1"], metadatas: [{ src: "a" }] }); // no documents/embeddings -> throws
// after
await collection.add({
ids: ["doc1"],
documents: ["the text to embed"],
metadatas: [{ src: "a" }],
}); Defensive patterns
Strategy: validation
Validate before calling
function assertAddParams(params: { ids: string[]; documents?: string[]; embeddings?: number[][] }) {
if (!params.documents && !params.embeddings) {
throw new Error("collection.add requires documents (to embed) or embeddings; got neither.");
}
}
assertAddParams(params);
await collection.add(params); Prevention
- Build add() params from a typed record shape ({ id, text }) so documents can never be silently undefined.
- Add a unit assertion in ingestion pipelines that documents.length > 0 before calling add().
When it happens
Trigger: collection.add({ ids: ['1'] }); collection.upsert({ ids, metadatas }) without documents or embeddings; code building params dynamically where params.documents ends up undefined (destructuring, optional chaining, an early return upstream).
Common situations: Indexing rows that only have metadata and expecting the server to embed metadata; a bug in record-building code silently producing undefined documents; porting code from another vector DB where ids-only inserts are allowed.
Related errors
- ids, embeddings, metadatas, and documents must all be the sa
- Failed to generate embeddings for your request.
- Expected ids to be strings, found ${typeof ids[i]} at index
- At least one of '${embeddingsField}' and '${documentsField}'
- Expected Embeddings to be non-empty list or numpy array, got
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/0a157ae2247e67c3.
Report an issue: GitHub.