chroma-core/chroma · error · ValueError

Google Generative AI only supports text documents, not image

Error message

Google Generative AI only supports text documents, not images

What it means

The legacy GoogleGenerativeAiEmbeddingFunction.__call__ verifies every input element is a str before calling genai.embed_content. The Gemini text-embedding API it wraps has no image input, so any non-string entry (image bytes, PIL objects, None, ints) is rejected up front.

Source

Thrown at chromadb/utils/embedding_functions/google_embedding_function.py:283

        genai.configure(
            api_key=self.api_key,
            client_options={"headers": {"x-goog-api-client": f"chroma/{__version__}"}},
        )
        self._genai = genai

    def __call__(self, input: Documents) -> Embeddings:
        """
        Generate embeddings for the given documents.

        Args:
            input: Documents to generate embeddings for.

        Returns:
            Embeddings for the documents.
        """
        if not all(isinstance(item, str) for item in input):
            raise ValueError(
                "Google Generative AI only supports text documents, not images"
            )

        embeddings_list: List[npt.NDArray[np.float32]] = []
        for text in input:
            kwargs: Dict[str, Any] = {
                "model": self.model_name,
                "content": text,
                "task_type": self.task_type,
            }
            if self.dimension is not None:
                kwargs["output_dimensionality"] = self.dimension
            embedding_result = self._genai.embed_content(**kwargs)
            embeddings_list.append(
                np.array(embedding_result["embedding"], dtype=np.float32)
            )

        return cast(Embeddings, embeddings_list)

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Filter or coerce inputs to strings before calling: [d for d in docs if isinstance(d, str)]
  2. For image/multimodal workloads use a multimodal embedding function (e.g. a CLIP-based one) instead
  3. Sanitize upstream data so missing content never reaches the embedding function

Example fix

# before
vecs = ef(["a cat photo", open('cat.jpg', 'rb').read()])  # ValueError: only supports text documents

# after
texts = [d for d in docs if isinstance(d, str)]
vecs = ef(texts)  # embed images with a separate multimodal embedding function
Defensive patterns

Strategy: type-guard

Validate before calling

texts = [d for d in docs if isinstance(d, str)]
if not texts:
    raise ValueError("no text documents to embed")
vecs = ef(texts)

Type guard

from typing import Any, Iterable, TypeGuard

def is_text_only(docs: Any) -> TypeGuard[list[str]]:
    return isinstance(docs, (list, tuple)) and all(isinstance(d, str) for d in docs)

if is_text_only(docs):
    vecs = ef(docs)
else:
    texts = [d for d in docs if isinstance(d, str)]
    vecs = ef(texts)  # route images to a multimodal embedding function separately

Prevention

When it happens

Trigger: Passing document lists containing bytes (e.g. image file contents), None from missing fields, or numbers; attempting multimodal retrieval with this text-only function.

Common situations: Building image search and reusing the text embedding function; DataFrame columns with NaN/None; JSON documents with null content fields.

Related errors


AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16). Data as JSON: /api/errors/cb6a5d0a61ae09f7. Report an issue: GitHub.