{"record":{"id":"0ea0425689034ce7","repo":"chroma-core/chroma","slug":"expected-documents-to-be-a-non-empty-list-got-le","errorCode":null,"errorMessage":"Expected documents to be a non-empty list, got {len(documents)} documents","messagePattern":"Expected documents to be a non-empty list, got (.+?) documents","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"chromadb/api/types.py","lineNumber":1447,"sourceCode":"        raise ValueError(\n            f\"Expected sparse vectors to be a non-empty list, got {len(vectors)} sparse vectors\"\n        )\n    for i, vector in enumerate(vectors):\n        if not isinstance(vector, SparseVector):\n            raise ValueError(\n                f\"Expected SparseVector instance at position {i}, got {type(vector).__name__}\"\n            )\n    return vectors\n\n\ndef validate_documents(documents: Documents, nullable: bool = False) -> None:\n    \"\"\"Validates documents to ensure it is a list of strings\"\"\"\n    if not isinstance(documents, list):\n        raise ValueError(\n            f\"Expected documents to be a list, got {type(documents).__name__}\"\n        )\n    if len(documents) == 0:\n        raise ValueError(\n            f\"Expected documents to be a non-empty list, got {len(documents)} documents\"\n        )\n    for document in documents:\n        # If embeddings are present, some documents can be None\n        if document is None and nullable:\n            continue\n        if not is_document(document):\n            raise ValueError(f\"Expected document to be a str, got {document}\")\n\n\ndef validate_images(images: Images) -> None:\n    \"\"\"Validates images to ensure it is a list of numpy arrays\"\"\"\n    if not isinstance(images, list):\n        raise ValueError(f\"Expected images to be a list, got {type(images).__name__}\")\n    if len(images) == 0:\n        raise ValueError(\n            f\"Expected images to be a non-empty list, got {len(images)} images\"\n        )","sourceCodeStart":1429,"sourceCodeEnd":1465,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/chromadb/api/types.py#L1429-L1465","documentation":"validate_documents rejects an empty documents list (len == 0). At least one document must accompany an add/upsert call; the message echoes the zero count. Individual None entries are permitted only when embeddings are also present (nullable=True), but an entirely empty list is never valid.","triggerScenarios":"collection.add(ids=[], documents=[]) — an upstream loader/chunker produced zero rows; a batch loop iterating an empty file set; filtering that removed every document from the batch.","commonSituations":"Directory ingestion where a folder contains no valid files; chunkers returning [] for blank/tiny documents; ETL stages filtering aggressively then still calling add(); empty-batch edge case in scheduled jobs.","solutions":["Guard the call: if documents: collection.add(ids=ids, documents=documents)","Fix or loosen the upstream loader/chunker so batches are non-empty when data exists","Log batch sizes during ingestion to catch silent zero-length batches early"],"exampleFix":"# before\ncollection.add(ids=ids, documents=chunks)  # chunks == []\n\n# after\nif chunks:\n    collection.add(ids=ids, documents=chunks)\nelse:\n    logger.warning(\"skipped empty batch for %s\", source)","handlingStrategy":"validation","validationCode":"def add_batch(collection, ids, documents, metadatas=None):\n    if not documents:\n        logger.warning(\"skipping empty document batch\")\n        return False\n    collection.add(ids=ids, documents=documents, metadatas=metadatas)\n    return True","typeGuard":"def is_non_empty_document_list(docs) -> bool:\n    return isinstance(docs, list) and len(docs) > 0 and all(isinstance(d, str) for d in docs)","tryCatchPattern":"try:\n    collection.add(ids=ids, documents=chunks, metadatas=metas)\nexcept ValueError as e:\n    if \"non-empty list, got 0 documents\" in str(e):\n        logger.warning(\"empty batch from loader — skipped\")\n    else:\n        raise","preventionTips":["Guard every ingestion loop with 'if not chunks: continue'","Check chunker/loader results before embedding so you never pay for a rejected batch","Treat empty-file/empty-folder cases as skips, not errors, in ETL wrappers"],"tags":["chromadb","documents","empty-list","batching"],"backgroundTag":"invalid-document-format","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}