{"record":{"id":"21d64dc70753a788","repo":"chroma-core/chroma","slug":"input-documents-cannot-be-empty","errorCode":null,"errorMessage":"Input documents cannot be empty","messagePattern":"Input documents cannot be empty","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"chromadb/utils/embedding_functions/google_embedding_function.py","lineNumber":90,"sourceCode":"            project=project,\n            location=location,\n            http_options=types.HttpOptions(\n                headers={\"x-goog-api-client\": f\"chroma/{__version__}\"}\n            ),\n        )\n\n    def __call__(self, input: Documents) -> Embeddings:\n        \"\"\"\n        Generate embeddings for the given documents.\n\n        Args:\n            input: Documents to generate embeddings for.\n\n        Returns:\n            Embeddings for the documents.\n        \"\"\"\n        if not input:\n            raise ValueError(\"Input documents cannot be empty\")\n        if not isinstance(input, (list, tuple)):\n            raise ValueError(\"Input must be a list or tuple of documents\")\n        if not all(isinstance(doc, str) for doc in input):\n            raise ValueError(\"All input documents must be strings\")\n\n        from google.genai.types import EmbedContentConfig\n\n        config = EmbedContentConfig(\n            task_type=self.task_type,\n            output_dimensionality=self.dimension,\n        )\n\n        try:\n            response = self.client.models.embed_content(\n                model=self.model_name,\n                contents=input,\n                config=config,\n            )","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/chromadb/utils/embedding_functions/google_embedding_function.py#L72-L108","documentation":"GoogleGeminiEmbeddingFunction.__call__ rejects empty input before contacting the API. The Gemini embed_content endpoint requires at least one content item, and embedding zero documents is meaningless, so a falsy input (empty list/tuple) raises immediately.","triggerScenarios":"Calling ef([]) directly; passing an empty batch produced by chunking code whose last chunk is empty; query flows where the query_texts filter or user input produced zero items; collection.query with an empty documents/query_texts list reaching the embedding function.","commonSituations":"Batch ingestion loops that slice documents into fixed-size chunks and send a final empty remainder; upstream filters that legitimately return zero matches but are still passed to the embedding function; empty user search box submitted without validation.","solutions":["Short-circuit before embedding: if the batch is empty, skip the call or return []","Fix chunking logic so it never yields an empty final chunk (e.g. range(0, n, size))","Validate user-supplied query text is non-empty before calling collection.query"],"exampleFix":"# before\nef = GoogleGeminiEmbeddingFunction()\nvecs = ef(batch)  # crashes when batch == []\n\n# after\nef = GoogleGeminiEmbeddingFunction()\nvecs = ef(batch) if batch else []","handlingStrategy":"validation","validationCode":"def safe_embed(ef, docs):\n    if not docs:\n        return []  # nothing to embed; skip the API entirely\n    return ef(docs)","typeGuard":"from typing import Any\n\ndef is_nonempty_batch(docs: Any) -> bool:\n    return isinstance(docs, (list, tuple)) and len(docs) > 0","tryCatchPattern":null,"preventionTips":["Guard batch loops: if not batch: continue","Fix chunkers to never emit an empty final chunk (range(0, len(docs), size))","Validate user query text is non-empty before calling collection.query"],"tags":["gemini","input-validation","empty-input","chroma"],"backgroundTag":"empty-input-validation","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}