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
- Stringify ids at the boundary: ids: rows.map((r) => String(r.id)).
- 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.
- 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
- Map external primary keys to strings exactly once, at ingestion time, and use that form for add/get/update/delete alike.
- Enable strict TypeScript checks (no implicit any) so numeric id arrays from untyped sources get caught earlier.
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
- embeddings and documents cannot both be undefined
- ids, embeddings, metadatas, and documents must all be the sa
- Failed to generate embeddings for your request.
- ID's must be unique, found duplicates for: ${duplicateIds}
- Expected 'ids' to be an array, but got ${typeof ids}
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/bc3d0992160dbdea.
Report an issue: GitHub.