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

  1. Pass documents so the embedding function can generate vectors: collection.add({ ids, documents }).
  2. Or pass precomputed embeddings: collection.add({ ids, embeddings }) — one vector per id.
  3. 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

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


AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16). Data as JSON: /api/errors/0a157ae2247e67c3. Report an issue: GitHub.