chroma-core/chroma · error

Failed to generate embeddings for your request.

Error message

Failed to generate embeddings for your request.

What it means

After the both-undefined guard, prepareRecordRequest() computes embeddingsArray as the caller-supplied embeddings or `await embeddingFunction.generate(documents)`. If that call returns a falsy value (undefined/null), this error is thrown for add/upsert requests. It almost always means the embedding function itself returned nothing — typically a custom IEmbeddingFunction whose generate() is missing a return or returns undefined on edge inputs.

Source

Thrown at clients/js/packages/chromadb-core/src/utils.ts:127

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}`,
      );
    }
  }

  if (
    (embeddingsArray !== undefined && ids.length !== embeddingsArray.length) ||
    (metadatas !== undefined && ids.length !== metadatas.length) ||
    (documents !== undefined && ids.length !== documents.length)
  ) {
    throw new Error(
      "ids, embeddings, metadatas, and documents must all be the same length",
    );

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Call the embedding function directly to see the return value: const out = await fn.generate(['ping']); console.log(out?.length, out?.[0]?.length) — you should get [1] and the vector dimension.
  2. Fix generate() to always return number[][] with exactly one vector per input string, including for edge-case inputs.
  3. Unit-test your IEmbeddingFunction implementation against that contract.

Example fix

// before (custom embedding function with no return)
class MyEmbedding {
  async generate(texts: string[]) {
    texts.map((t) => embed(t)); // missing return -> undefined
  }
}

// after
class MyEmbedding {
  async generate(texts: string[]): Promise<number[][]> {
    return texts.map((t) => embed(t)); // always one vector per input
  }
}
Defensive patterns

Strategy: validation

Validate before calling

// Contract-check your embedding function before wiring it into a collection
async function assertEmbeddingContract(fn: IEmbeddingFunction) {
  const out = await fn.generate(["ping"]);
  if (!Array.isArray(out) || out.length !== 1 || !Array.isArray(out[0])) {
    throw new Error("IEmbeddingFunction.generate must return number[][] with one vector per input");
  }
}
await assertEmbeddingContract(myCustomFn);

Type guard

const isEmbeddingMatrix = (v: unknown): v is number[][] =>
  Array.isArray(v) && v.length > 0 && v.every((row) => Array.isArray(row) && row.every((x) => typeof x === "number"));

Prevention

When it happens

Trigger: collection.add({ ids, documents }) where the collection's embedding function is a custom class whose generate(texts) has no return statement, returns undefined for empty/whitespace strings, or returns null on an error path; a default embedding function misconfigured so generate silently yields undefined.

Common situations: First run of a hand-written custom IEmbeddingFunction; an `async generate(...)` that does `if (!texts.length) return;` for empty batches; refactors where the return got dropped; generate() that awaits a helper which itself returns undefined.

Related errors


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