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

  1. Find the empty vector position before sending: embeddings.findIndex(e => e.length === 0), then fix or remove that record.
  2. Filter out empty/blank documents before calling add() so the embedding function never receives them.
  3. If a custom embedding function returns [] on failure, make it throw instead, or drop the failed record from the batch.
  4. 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

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


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