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
- 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.
- Fix generate() to always return number[][] with exactly one vector per input string, including for edge-case inputs.
- 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
- Unit-test custom IEmbeddingFunction.generate (including empty-string and empty-array inputs) for shape and count.
- Type generate()'s return as Promise<number[][]> so a missing return is a compile error, not a runtime surprise.
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
- embeddings and documents cannot both be undefined
- At least one of '${embeddingsField}' and '${documentsField}'
- The model name cannot be changed after initialization.
- The task type cannot be changed after initialization.
- Changing the URL is not allowed.
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/a959d45a4db9cfeb.
Report an issue: GitHub.