{"record":{"id":"af0d86feee70a75b","repo":"chroma-core/chroma","slug":"expected-sparse-vectors-to-be-a-non-empty-list-go","errorCode":null,"errorMessage":"Expected sparse vectors to be a non-empty list, got {len(vectors)} sparse vectors","messagePattern":"Expected sparse vectors to be a non-empty list, got (.+?) sparse vectors","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"chromadb/api/types.py","lineNumber":1429,"sourceCode":"def validate_sparse_vectors(vectors: SparseVectors) -> SparseVectors:\n    \"\"\"Validates sparse vectors to ensure it is a non-empty list of SparseVector instances.\n\n    This function validates the structure and types of sparse vectors returned by\n    SparseEmbeddingFunction implementations. It ensures:\n    - Vectors is a list\n    - List is non-empty\n    - All items are SparseVector instances\n\n    Note: Individual SparseVector validation (sorted indices, non-negative values, etc.)\n    happens automatically in SparseVector.__post_init__ when each instance is created.\n    This function only validates the list structure and instance types.\n    \"\"\"\n    if not isinstance(vectors, list):\n        raise ValueError(\n            f\"Expected sparse vectors to be a list, got {type(vectors).__name__}\"\n        )\n    if len(vectors) == 0:\n        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(","sourceCodeStart":1411,"sourceCodeEnd":1447,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/chromadb/api/types.py#L1411-L1447","documentation":"validate_sparse_vectors rejects an empty list (len == 0). At least one SparseVector must be present, mirroring the dense-embeddings rule; the message echoes the zero count.","triggerScenarios":"A SparseEmbeddingFunction invoked on an empty input list returning []; calling add()/query() with sparse_vectors=[]; batch loops that don't skip empty batches.","commonSituations":"Hybrid-search pipelines where chunking or filtering produced zero texts for one batch; per-file processing of empty files; reusing the dense-pipeline guard code that was never written.","solutions":["Skip the call when there is nothing to embed: if not texts: return []","Guard at the call site: if sparse_vectors: collection.add(..., sparse_vectors=sparse_vectors)","Fix upstream filtering that dropped every row in the batch"],"exampleFix":"# before\nsv = sparse_ef(texts)              # texts == [] -> []\ncollection.add(ids=ids, sparse_vectors=sv, documents=texts)\n\n# after\nif texts:\n    sv = sparse_ef(texts)\n    collection.add(ids=ids, sparse_vectors=sv, documents=texts)","handlingStrategy":"validation","validationCode":"def sparse_add(collection, ids, texts, sparse_ef):\n    if not texts:\n        return  # nothing to embed — skip instead of calling with []\n    sv = sparse_ef(texts)\n    if not sv:\n        raise ValueError(\"sparse embedding function returned an empty list for non-empty input\")\n    collection.add(ids=ids, documents=texts, sparse_vectors=sv)","typeGuard":"def is_non_empty_sparse_list(v) -> bool:\n    return isinstance(v, list) and len(v) > 0","tryCatchPattern":"try:\n    collection.query(query_texts=[q], sparse_vectors=sv if sv else None)\nexcept ValueError as e:\n    if \"non-empty list, got 0 sparse vectors\" in str(e):\n        logger.warning(\"empty sparse batch skipped\")\n    else:\n        raise","preventionTips":["Short-circuit empty text batches before invoking the sparse embedder","Assert len(texts) == len(sparse_vectors) after every EF call — catches empty/unbalanced outputs","Guard hybrid pipelines where either dense or sparse side can be empty"],"tags":["chromadb","sparse-vectors","empty-list","batching"],"backgroundTag":"sparse-vector-validation","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}