{"record":{"id":"a6a1da9e247fc67c","repo":"chroma-core/chroma","slug":"unequal-lengths-for-fields-error-str","errorCode":null,"errorMessage":"Unequal lengths for fields: {error_str}","messagePattern":"Unequal lengths for fields: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"chromadb/api/types.py","lineNumber":473,"sourceCode":"            f\"At least one of one of {', '.join(record_set.keys())} must be provided\"\n        )\n\n    zero_lengths = [\n        key\n        for key, lst in record_set.items()\n        if lst is not None and len(lst) == 0  # type: ignore[arg-type]\n    ]\n\n    if zero_lengths:\n        raise ValueError(f\"Non-empty lists are required for {zero_lengths}\")\n\n    if len(set(lengths)) > 1:\n        error_str = \", \".join(\n            f\"{key}: {len(lst)}\"\n            for key, lst in record_set.items()\n            if lst is not None  # type: ignore[arg-type]\n        )\n        raise ValueError(f\"Unequal lengths for fields: {error_str}\")\n\n\ndef validate_record_set_for_embedding(\n    record_set: BaseRecordSet, embeddable_fields: Optional[Set[str]] = None\n) -> None:\n    \"\"\"\n    Validates that the Record is ready to be embedded, i.e. that it contains exactly one of the embeddable fields.\n    \"\"\"\n    if record_set[\"embeddings\"] is not None:\n        raise ValueError(\"Attempting to embed a record that already has embeddings.\")\n    if embeddable_fields is None:\n        embeddable_fields = get_default_embeddable_record_set_fields()\n    validate_record_set_contains_one(record_set, embeddable_fields)\n\n\ndef validate_record_set_contains_any(\n    record_set: BaseRecordSet, contains_any: Set[str]\n) -> None:","sourceCodeStart":455,"sourceCodeEnd":491,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/chromadb/api/types.py#L455-L491","documentation":"Chroma validates every batch write (add/upsert/update) client-side before any data reaches storage. It normalizes all list arguments (ids, embeddings, metadatas, documents, images, uris) into a record set, and _validate_record_set_length_consistency (chromadb/api/types.py:450, called from validate_insert_record_set) requires every provided list to have the same length. When two or more provided lists disagree, it raises this error with a per-field length report so you can see exactly which lists are out of sync.","triggerScenarios":"collection.add(ids=['a','b','c'], documents=['only-one']) (3 ids vs 1 document); upsert where metadatas came from df.head(10) but ids has 25 entries; update where embeddings has a different count than ids; passing one scalar argument (auto-wrapped to length 1 by maybe_cast_one_to_many) alongside N ids, e.g. add(ids=[...], documents='single doc').","commonSituations":"Building ids/documents/metadatas in separate loops or comprehensions that drift out of sync; slicing a dataframe per column with different limits (df['id'][:200] vs df['text'][:100]); concatenating partial batches; off-by-one range() bugs; precomputed embedding arrays sized for a different batch.","solutions":["Make every provided list the same length as ids (the message lists each field with its length - align the offenders first)","Add an assert before the call: assert len(ids) == len(documents) == len(metadatas)","Build a single list of record dicts and derive each column from it (ids=[r['id'] for r in records], documents=[r['text'] for r in records]) so lengths cannot diverge","When sourcing from a dataframe, slice the frame once (df = df.head(n)) and then read each column"],"exampleFix":"# before\ncollection.add(ids=ids, documents=docs, metadatas=metas)  # lengths drifted apart\n\n# after\nassert len(ids) == len(docs) == len(metas), f'{len(ids)} vs {len(docs)} vs {len(metas)}'\ncollection.add(ids=ids, documents=docs, metadatas=metas)","handlingStrategy":"validation","validationCode":"def assert_batch_lengths(ids, **fields):\n    n = len(ids)\n    bad = {name: len(v) for name, v in fields.items() if v is not None and len(v) != n}\n    if bad:\n        raise ValueError(f'Length mismatch vs ids({n}): {bad}')\n\nassert_batch_lengths(ids, documents=docs, metadatas=metas, embeddings=embs)\ncollection.add(ids=ids, documents=docs, metadatas=metas, embeddings=embs)","typeGuard":"def batch_is_consistent(ids, **fields) -> bool:\n    return all(v is None or len(v) == len(ids) for v in fields.values())","tryCatchPattern":"try:\n    collection.add(ids=ids, documents=docs, metadatas=metas)\nexcept ValueError as e:\n    if 'Unequal lengths for fields' in str(e):\n        logger.error('batch column drift', extra={'lens': {k: len(v) for k, v in [('ids', ids), ('documents', docs), ('metadatas', metas)]}})\n    raise","preventionTips":["Derive every column from a single list of record dicts so lengths cannot diverge","Assert lengths in debug builds or CI fixtures","Slice dataframes once, then read columns","Log per-column lengths before each batch write"],"tags":["chromadb","python","validation","batch-insert","argument-mismatch"],"backgroundTag":"argument-length-mismatch","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}