chroma-core/chroma · error · ValueError

Expected embeddings to be a list, got {type(embeddings).__na

Error message

Expected embeddings to be a list, got {type(embeddings).__name__}

What it means

validate_embeddings requires the embeddings argument to be a Python list or numpy ndarray. Any other type — generator, tuple, string, dict, None — raises this ValueError, with the message reporting the offending type name.

Source

Thrown at chromadb/api/types.py:1375

def validate_n_results(n_results: int) -> int:
    """Validates n_results to ensure it is a positive Integer. Since hnswlib does not allow n_results to be negative."""
    # Check Number of requested results
    if not isinstance(n_results, int):
        raise ValueError(
            f"Expected requested number of results to be a int, got {n_results}"
        )
    if n_results <= 0:
        raise TypeError(
            f"Number of requested results {n_results}, cannot be negative, or zero."
        )
    return n_results


def validate_embeddings(embeddings: Embeddings) -> Embeddings:
    """Validates embeddings to ensure it is a list of numpy arrays of ints, or floats"""
    if not isinstance(embeddings, (list, np.ndarray)):
        raise ValueError(
            f"Expected embeddings to be a list, got {type(embeddings).__name__}"
        )
    if len(embeddings) == 0:
        raise ValueError(
            f"Expected embeddings to be a list with at least one item, got {len(embeddings)} embeddings"
        )
    if not all([isinstance(e, np.ndarray) for e in embeddings]):
        raise ValueError(
            "Expected each embedding in the embeddings to be a numpy array, got "
            f"{list(set([type(e).__name__ for e in embeddings]))}"
        )
    for i, embedding in enumerate(embeddings):
        if embedding.ndim == 0:
            raise ValueError(
                f"Expected a 1-dimensional array, got a 0-dimensional array {embedding}"
            )
        if embedding.size == 0:
            raise ValueError(

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Materialize iterables: embeddings=list(embeddings)
  2. Convert tuples: embeddings=list(tuples) — tuple is not accepted even though it is sequence-like
  3. If your custom embedding function returns an ndarray, wrap as list(arr) or keep the ndarray itself (both accepted)

Example fix

# before
results = collection.query(query_embeddings=map(ef, [query]), n_results=5)

# after
results = collection.query(query_embeddings=list(map(ef, [query])), n_results=5)
Defensive patterns

Strategy: type-guard

Validate before calling

def materialize_embeddings(embeddings):
    if isinstance(embeddings, (list, np.ndarray)):
        return embeddings
    return list(embeddings)  # materialize generators/maps/tuples

res = collection.query(query_embeddings=materialize_embeddings(embeds), n_results=5)

Type guard

import numpy as np

def is_embeddings_container(v) -> bool:
    return isinstance(v, (list, np.ndarray))

Try / catch

try:
    collection.add(ids=ids, embeddings=embeddings, documents=docs)
except ValueError as e:
    if "Expected embeddings to be a list" in str(e):
        collection.add(ids=ids, embeddings=list(embeddings), documents=docs)
    else:
        raise

Prevention

When it happens

Trigger: Passing a generator or map object (embeddings=map(ef, texts)) instead of materializing it; passing a tuple of arrays; passing the output of an embedding function that returns a bare ndarray-of-ndarray or a dict keyed by id; passing None where embeddings are required (e.g. query_embeddings=None).

Common situations: Streaming/pipeline code that keeps lazy iterators; tuple literals used for immutability; custom EmbeddingFunction implementations with non-standard return shapes; version changes where a wrapper stopped calling list().

Related errors


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