{"record":{"id":"725f40f8f69a31c9","repo":"chroma-core/chroma","slug":"ids-embeddings-metadatas-and-documents-must-all","errorCode":null,"errorMessage":"ids, embeddings, metadatas, and documents must all be the same length","messagePattern":"ids, embeddings, metadatas, and documents must all be the same length","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"clients/js/packages/chromadb-core/src/utils.ts","lineNumber":143,"sourceCode":"\n  if (!embeddingsArray && !update) {\n    throw new Error(\"Failed to generate embeddings for your request.\");\n  }\n\n  for (let i = 0; i < ids.length; i += 1) {\n    if (typeof ids[i] !== \"string\") {\n      throw new Error(\n        `Expected ids to be strings, found ${typeof ids[i]} at index ${i}`,\n      );\n    }\n  }\n\n  if (\n    (embeddingsArray !== undefined && ids.length !== embeddingsArray.length) ||\n    (metadatas !== undefined && ids.length !== metadatas.length) ||\n    (documents !== undefined && ids.length !== documents.length)\n  ) {\n    throw new Error(\n      \"ids, embeddings, metadatas, and documents must all be the same length\",\n    );\n  }\n\n  const uniqueIds = new Set(ids);\n  if (uniqueIds.size !== ids.length) {\n    const duplicateIds = ids.filter(\n      (item, index) => ids.indexOf(item) !== index,\n    );\n    throw new Error(\n      `ID's must be unique, found duplicates for: ${duplicateIds}`,\n    );\n  }\n\n  if (\n    embeddingsArray &&\n    embeddingsArray.some((embedding) => embedding.length === 0)\n  ) {","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/clients/js/packages/chromadb-core/src/utils.ts#L125-L161","documentation":"prepareRecordRequest() cross-checks that ids, embeddings (as supplied or as generated from documents), metadatas, and documents all have the same length; any mismatch throws before the request is sent. This guards the server from pairing record i's id with record j's vector. Note it checks array lengths only — per-vector dimensionality is validated server-side.","triggerScenarios":"collection.add({ ids, documents, metadatas }) where metadatas was built for a different chunking/batch than documents; passing precomputed embeddings computed from a different text array; slicing one array during batching but not the others; a retry path that reuses ids but rebuilds documents with a filter.","commonSituations":"Chunked ingestion pipelines where embeddings are cached from a previous chunking run; off-by-one in batch slicing; mapping/filtering one array (documents.filter(...)) while keeping ids and metadatas unfiltered.","solutions":["Assert equal lengths before add: if (ids.length !== documents.length) throw new Error(...) with batch context.","When using precomputed embeddings, compute them from the exact documents array passed in this call.","Rebuild all arrays from a single source-of-truth list of records ({ id, document, metadata }) so they cannot diverge.","After any filter/map/slice on one array, apply the identical transformation to the others."],"exampleFix":"// before\nawait collection.add({\n  ids, // 10 ids\n  documents, // 10 documents\n  metadatas: metadatas.slice(0, 8), // stale slice -> length mismatch\n});\n\n// after\nconst batch = records.slice(offset, offset + size); // single source of truth\nawait collection.add({\n  ids: batch.map((r) => r.id),\n  documents: batch.map((r) => r.text),\n  metadatas: batch.map((r) => r.meta),\n});","handlingStrategy":"validation","validationCode":"function assertEqualLengths(p: {\n  ids: string[];\n  embeddings?: number[][];\n  metadatas?: Record<string, unknown>[];\n  documents?: string[];\n}) {\n  const n = p.ids.length;\n  const parts: [string, number | undefined][] = [\n    [\"embeddings\", p.embeddings?.length],\n    [\"metadatas\", p.metadatas?.length],\n    [\"documents\", p.documents?.length],\n  ];\n  const bad = parts.filter(([, len]) => len !== undefined && len !== n);\n  if (bad.length) throw new Error(`Length mismatch vs ids(${n}): ${bad.map(([k, l]) => `${k}(${l})`).join(\", \")}`);\n}\nassertEqualLengths(params);\nawait collection.add(params);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Derive ids/documents/metadatas/embeddings from one array of record objects so lengths cannot diverge.","Never apply filter/slice to one of the parallel arrays without applying it to all of them.","When reusing cached embeddings, key the cache by the exact document list it was computed from."],"tags":["records","add","upsert","length-mismatch","validation","batching"],"backgroundTag":"record-array-length-mismatch","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}