chroma-core/chroma · error · ValueError

Expected Embeddings to be non-empty list or numpy array, got

Error message

Expected Embeddings to be non-empty list or numpy array, got {target}

What it means

normalize_embeddings, which runs on the embeddings argument of add/upsert/query, rejects empty input: when len(target) == 0 it raises ValueError('Expected Embeddings to be non-empty list or numpy array'). If embeddings are provided at all, they must contain at least one vector — there is no meaningful empty write or empty query.

Source

Thrown at chromadb/api/types.py:230

    for b64_string in b64_strings:
        if b64_string is None:
            embeddings.append(None)  # type: ignore
        else:
            packed_data = pybase64.b64decode(b64_string)
            vector_length = len(packed_data) // 4
            embedding_tuple = _get_struct(vector_length).unpack(packed_data)
            embeddings.append(list(embedding_tuple))
    return embeddings


def normalize_embeddings(
    target: Optional[Union[OneOrMany[Embedding], OneOrMany[PyEmbedding]]],
) -> Optional[Embeddings]:
    if target is None:
        return None

    if len(target) == 0:
        raise ValueError(
            f"Expected Embeddings to be non-empty list or numpy array, got {target}"
        )

    if isinstance(target, np.ndarray):
        if target.ndim == 1:
            return [target]
        elif target.ndim == 2:
            return [row for row in target]
    elif isinstance(target, list):
        # One PyEmbedding
        if isinstance(target[0], (int, float)) and not isinstance(target[0], bool):
            return [np.array(target, dtype=np.float32)]
        elif isinstance(target[0], np.ndarray):
            return cast(Embeddings, target)
        elif isinstance(target[0], list):
            if isinstance(target[0][0], (int, float)) and not isinstance(
                target[0][0], bool
            ):

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Skip the call when the batch is empty: if not embeddings: return
  2. Fix upstream producers so empty batches never reach the client
  3. Pass None (letting the collection's embedding function compute) rather than an empty list when you have documents but no vectors

Example fix

// before
coll.add(ids=ids, embeddings=embs)  # embs == [] -> ValueError

// after
if embs:
    coll.add(ids=ids, embeddings=embs)
Defensive patterns

Strategy: validation

Validate before calling

def add_batch(coll, ids, embeddings):
    if not embeddings:
        return  # nothing to write — skip instead of erroring
    coll.add(ids=ids, embeddings=embeddings)

def query_safe(coll, query_embeddings):
    if not query_embeddings:
        return None
    return coll.query(query_embeddings=query_embeddings)

Prevention

When it happens

Trigger: coll.add(ids=[], embeddings=[]), coll.query(query_embeddings=[]), or passing np.array([]) — any zero-length embeddings list or array.

Common situations: Ingestion loops that call add() on an empty batch instead of skipping it; an embedding function returning [] for empty text; batch pipelines handing off empty DataFrames.

Related errors


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