{"record":{"id":"2770491c32bd6d67","repo":"chroma-core/chroma","slug":"exactly-one-of-join-contains-one-must-be-p","errorCode":null,"errorMessage":"Exactly one of {', '.join(contains_one)} must be provided","messagePattern":"Exactly one of (.+?) must be provided","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"chromadb/api/types.py","lineNumber":509,"sourceCode":") -> None:\n    \"\"\"\n    Validates that at least one of the fields in contains_any is not None.\n    \"\"\"\n    _validate_record_set_contains(record_set, contains_any)\n\n    if not any(record_set[field] is not None for field in contains_any):  # type: ignore[literal-required]\n        raise ValueError(f\"At least one of {', '.join(contains_any)} must be provided\")\n\n\ndef validate_record_set_contains_one(\n    record_set: BaseRecordSet, contains_one: Set[str]\n) -> None:\n    \"\"\"\n    Validates that exactly one of the fields in contains_one is not None.\n    \"\"\"\n    _validate_record_set_contains(record_set, contains_one)\n    if sum(record_set[field] is not None for field in contains_one) != 1:  # type: ignore[literal-required]\n        raise ValueError(f\"Exactly one of {', '.join(contains_one)} must be provided\")\n\n\ndef _validate_record_set_contains(\n    record_set: BaseRecordSet, contains: Set[str]\n) -> None:\n    \"\"\"\n    Validates that all fields in contains are valid fields of the Record.\n    \"\"\"\n    if any(field not in record_set for field in contains):\n        raise ValueError(\n            f\"Invalid field in contains: {', '.join(contains)}, available fields: {', '.join(record_set.keys())}\"\n        )\n\n\nParameter = TypeVar(\"Parameter\", Document, Image, Embedding, Metadata, ID)\n\nInclude = List[\n    Literal[\"documents\", \"embeddings\", \"metadatas\", \"distances\", \"uris\", \"data\"]","sourceCodeStart":491,"sourceCodeEnd":527,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/chromadb/api/types.py#L491-L527","documentation":"validate_record_set_contains_one (chromadb/api/types.py:501), reached via validate_record_set_for_embedding, requires exactly one embeddable field to be present whenever Chroma must generate embeddings itself. For add/upsert/query the embeddable set is {'documents','images','uris'}; for update it is {'documents','images'}. Supplying none (nothing to embed) or more than one (ambiguous input) both raise this error. Passing explicit embeddings bypasses the check entirely.","triggerScenarios":"collection.query() with none of query_texts/query_embeddings/query_images/query_uris; collection.add(ids=[...], metadatas=[...]) with no embeddings, documents, images or uris (nothing to embed); collection.add(documents=[...], uris=[...]) (two embeddable fields); query(query_texts=[...], query_images=[...]); update(ids, documents=[...], images=[...]).","commonSituations":"Adding id-only or metadata-only records and expecting Chroma to accept them without vectors; generic search code that passes both text and image queries; forgetting that add() needs content to embed unless embeddings are supplied; code migrated from older versions with looser checks.","solutions":["If you want Chroma to embed: pass exactly one of documents, images or uris (typically documents)","If you already have vectors: pass embeddings= explicitly - documents then become optional payload","In query code, branch: use query_embeddings when available, otherwise exactly one of query_texts/query_images/query_uris","If you genuinely need metadata-only rows, reconsider whether a vector store fits, or store explicit placeholder embeddings"],"exampleFix":"# before\ncollection.add(ids=ids, metadatas=metas)  # nothing to embed\n\n# after\ncollection.add(ids=ids, metadatas=metas, documents=docs)  # exactly one embeddable field","handlingStrategy":"validation","validationCode":"provided = [name for name, v in {'documents': documents, 'images': images, 'uris': uris}.items() if v is not None]\nif embeddings is None and len(provided) != 1:\n    raise ValueError(f'pass exactly one of documents/images/uris (got {provided}) or supply embeddings')\ncollection.add(ids=ids, embeddings=embeddings, documents=documents, images=images, uris=uris)","typeGuard":"def exactly_one_embeddable(documents, images, uris) -> bool:\n    return sum(v is not None for v in (documents, images, uris)) == 1","tryCatchPattern":"try:\n    collection.query(query_texts=qtexts, query_embeddings=qembs, n_results=k)\nexcept ValueError as e:\n    if 'Exactly one of' in str(e):\n        # pick one input mode and retry\n        ...\n    raise","preventionTips":["Branch on input mode before calling add/query: embeddings vs exactly one content field","Reject metadata-only writes in your ingestion schema","For multimodal data, store text and images in separate collections or pass explicit embeddings"],"tags":["chromadb","python","embeddings","add","query","validation"],"backgroundTag":"mutually-exclusive-parameters","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}