chroma-core/chroma · error · ValueError

Embedding function returned unexpected number of embeddings

Error message

Embedding function returned unexpected number of embeddings

What it means

For a Knn expression whose query is a plain string on the main embedding field, Chroma embeds `[query_text]` with the collection's embedding function and expects exactly one embedding back. A custom function returning zero results or more than one (or a bare vector instead of a length-1 list) triggers this error.

Source

Thrown at chromadb/api/models/CollectionCommon.py:840

        """
        from chromadb.execution.expression.operator import Knn

        if not isinstance(knn, Knn):
            return knn

        # If query is not a string, nothing to do
        if not isinstance(knn.query, str):
            return knn

        query_text = knn.query
        key = knn.key

        # Handle main embedding field
        if key == EMBEDDING_KEY:
            # Use the collection's main embedding function
            embedding = self._embed(input=[query_text], is_query=True)
            if not embedding or len(embedding) != 1:
                raise ValueError(
                    "Embedding function returned unexpected number of embeddings"
                )
            # Return a new Knn with the embedded query
            return Knn(
                query=embedding[0],
                key=knn.key,
                limit=knn.limit,
                default=knn.default,
                return_rank=knn.return_rank,
            )

        # Handle metadata field with potential sparse embedding
        schema = self.schema
        if schema is None or key not in schema.keys:
            raise ValueError(
                f"Cannot embed string query for key '{key}': "
                f"key not found in schema. Please provide an embedded vector or "
                f"configure an embedding function for this key in the schema."

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Make embed_query return a list of length equal to the input list — for one input, exactly one embedding
  2. Wrap the EF to enforce the contract and get an early, clear failure: assert len(out) == len(input)
  3. Pass a precomputed vector as the Knn query instead of a string

Example fix

# before
class MyEF:
    def embed_query(self, input):
        return self._model.encode(input)      # may return wrong shape/length

# after
class MyEF:
    def embed_query(self, input):
        out = self._model.encode(input)
        out = list(out)
        assert len(out) == len(input)
        return out
Defensive patterns

Strategy: type-guard

Validate before calling

emb = collection._embedding_function.embed_query(["probe"])
assert len(emb) == 1  # fails fast before the real query

Type guard

def checked_ef(ef):
    def wrapped(input):
        out = list(ef(input))
        assert len(out) == len(input), f"EF returned {len(out)} for {len(input)} inputs"
        return out
    return wrapped

Prevention

When it happens

Trigger: `collection.query(where=Knn(query="some text", key="embedding", ...))` with a custom EmbeddingFunction whose embed_query/embed call returns the wrong shape for a single-item input list.

Common situations: Custom EFs that return a numpy array whose first dimension is not 1, that return a scalar embedding instead of a list, or that batch/collapse inputs internally.

Related errors


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