{"record":{"id":"792ead6f07d57016","repo":"chroma-core/chroma","slug":"at-least-one-of-one-of-join-record-set-keys","errorCode":null,"errorMessage":"At least one of one of {', '.join(record_set.keys())} must be provided","messagePattern":"At least one of one of (.+?) must be provided","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"chromadb/api/types.py","lineNumber":454,"sourceCode":"\n\ndef validate_insert_record_set(record_set: InsertRecordSet) -> None:\n    \"\"\"\n    Validates the InsertRecordSet, ensuring that all fields are of the right type and length.\n    \"\"\"\n    _validate_record_set_length_consistency(record_set)\n    validate_base_record_set(record_set)\n\n    validate_ids(record_set[\"ids\"])\n    if record_set[\"metadatas\"] is not None:\n        validate_metadatas(record_set[\"metadatas\"])\n\n\ndef _validate_record_set_length_consistency(record_set: BaseRecordSet) -> None:\n    lengths = [len(lst) for lst in record_set.values() if lst is not None]  # type: ignore[arg-type]\n\n    if not lengths:\n        raise ValueError(\n            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        )","sourceCodeStart":436,"sourceCodeEnd":472,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/chromadb/api/types.py#L436-L472","documentation":"Before add/update/upsert, Chroma validates the record set; _validate_record_set_length_consistency first requires that at least one field (ids, embeddings, metadatas, documents, uris, ...) be non-None. If every field is None it raises ValueError('At least one of one of {fields} must be provided') listing the record-set keys — the call carries no data at all.","triggerScenarios":"coll.add() with no arguments, or a dynamically built kwargs dict in which every value ended up None (all keys filtered out before the call).","commonSituations":"Dynamic batch builders that drop every key for degenerate rows; wrapper APIs forwarding **kwargs that collapsed to all-None; refactors that accidentally stop passing ids.","solutions":["Require ids at the wrapper level and skip empty batches: if not ids: return","Validate any(v is not None for v in record.values()) before calling add/upsert","Log the record set when validation fails so silent all-None dicts surface quickly"],"exampleFix":"// before\nrecord = {k: v for k, v in batch.items() if v}  # can end up empty\ncoll.add(**record)  # ValueError: at least one field must be provided\n\n// after\nif any(v is not None for v in batch.values()):\n    coll.add(**{k: v for k, v in batch.items() if v is not None})","handlingStrategy":"validation","validationCode":"def add_record_set(coll, **fields):\n    if all(v is None for v in fields.values()):\n        raise ValueError(f'record set is empty: provide at least one of {sorted(fields)}')\n    coll.add(**{k: v for k, v in fields.items() if v is not None})","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass ids explicitly — it is the natural anchor field for add/upsert","Skip empty batches before they reach the client","When building kwargs dynamically, assert at least one non-None value survives filtering"],"tags":["chroma","record-set","validation","missing-fields","add"],"backgroundTag":"missing-required-field","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}