chroma-core/chroma · error · ValueError

Input must be a list or tuple of documents

Error message

Input must be a list or tuple of documents

What it means

GoogleGeminiEmbeddingFunction.__call__ requires the input container itself to be a list or tuple. Generators, numpy arrays, pandas Series, and even a bare Python string all fail this isinstance check - a bare str is deliberately not accepted because it would be ambiguous (one document vs a sequence of characters).

Source

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

            http_options=types.HttpOptions(
                headers={"x-goog-api-client": f"chroma/{__version__}"}
            ),
        )

    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 input:
            raise ValueError("Input documents cannot be empty")
        if not isinstance(input, (list, tuple)):
            raise ValueError("Input must be a list or tuple of documents")
        if not all(isinstance(doc, str) for doc in input):
            raise ValueError("All input documents must be strings")

        from google.genai.types import EmbedContentConfig

        config = EmbedContentConfig(
            task_type=self.task_type,
            output_dimensionality=self.dimension,
        )

        try:
            response = self.client.models.embed_content(
                model=self.model_name,
                contents=input,
                config=config,
            )
        except Exception as e:
            raise ValueError(f"Failed to generate embeddings: {str(e)}") from e

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Materialize iterables: ef(list(docs))
  2. Wrap single documents in a list: ef(['hello'])
  3. Convert numpy arrays with .tolist() and pandas Series with .tolist() or list(series)

Example fix

# before
ef = GoogleGeminiEmbeddingFunction()
vecs = ef(df['text'].values)      # numpy array -> ValueError
vecs = ef('single document')      # bare str -> ValueError

# after
vecs = ef(df['text'].tolist())
vecs = ef(['single document'])
Defensive patterns

Strategy: type-guard

Validate before calling

docs = list(docs)  # materialize generators/arrays/Series before embedding
vecs = ef(docs)

Type guard

from typing import Any, TypeGuard

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

if is_document_list(docs):
    vecs = ef(docs)  # narrowed and safe
else:
    docs = list(docs) if not isinstance(docs, str) else [docs]
    vecs = ef(docs)

Prevention

When it happens

Trigger: Passing a generator expression (ef((d for d in docs))); a numpy array of strings (df['text'].values); a pandas Series; a single document as ef('hello') instead of ef(['hello']); any custom iterable that is not list/tuple.

Common situations: Data-science pipelines handing df['text'].values straight to the embedding function; map()/filter() results passed without materialization; single-document code paths that forget to wrap the string in a list.

Related errors


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