chroma-core/chroma · error

Expected ids to be strings, found ${typeof ids[i]} at index

Error message

Expected ids to be strings, found ${typeof ids[i]} at index ${i}

What it means

prepareRecordRequest() iterates ids and requires every element to be a JavaScript string; the first offender is reported with its typeof ('number', 'object', 'boolean', ...). Chroma record ids are strings on the wire (UUIDs or custom string ids), and silently coercing would risk silent data mismatches, so the client fails fast before sending anything.

Source

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

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

  const uniqueIds = new Set(ids);
  if (uniqueIds.size !== ids.length) {
    const duplicateIds = ids.filter(

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Stringify ids at the boundary: ids: rows.map((r) => String(r.id)).
  2. For UUID columns keep them strings; for numbers decide on a canonical format (e.g., String(n)) and use it consistently for add/get/update/delete.
  3. Log typeof of the reported index if unsure which record is malformed.

Example fix

// before
await collection.add({
  ids: [1, 2, 3], // typeof 'number' at index 0 -> throws
  documents: ["a", "b", "c"],
});

// after
await collection.add({
  ids: ["1", "2", "3"], // rows.map(r => String(r.id))
  documents: ["a", "b", "c"],
});
Defensive patterns

Strategy: type-guard

Validate before calling

// Coerce at the boundary — decide the canonical id format once
const ids = rows.map((r) => String(r.id));

Type guard

const isStringIdArray = (ids: unknown[]): ids is string[] =>
  ids.every((id) => typeof id === "string");

if (!isStringIdArray(ids)) {
  const i = ids.findIndex((id) => typeof id !== "string");
  throw new Error(`ids[${i}] is ${typeof ids[i]} — stringify ids before add()`);
}

Prevention

When it happens

Trigger: collection.add({ ids: [1, 2, 3], ... }) with numeric primary keys from a SQL table; ids containing null/undefined from a sparse array; Mongo ObjectId objects; ids: [crypto.randomUUID()] fine, but ids from JSON parsed with numbers kept as numbers.

Common situations: Bulk-importing rows whose primary keys are integers; mapping ORM rows and forgetting to stringify; passing BigInt ids (typeof 'bigint'); arrays built with a stray undefined hole.

Related errors


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