chroma-core/chroma · error · ValueError

Expected embeddings to be a list with at least one item, got

Error message

Expected embeddings to be a list with at least one item, got {len(embeddings)} embeddings

What it means

validate_embeddings rejects an empty list/ndarray (len == 0). At least one embedding must be present, because there is nothing to add or query otherwise. The message echoes the (zero) count.

Source

Thrown at chromadb/api/types.py:1379

    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(
                f"Expected each embedding in the embeddings to be a 1-dimensional numpy array with at least 1 int/float value. Got a 1-dimensional numpy array with no values at pos {i}"
            )

        if embedding.dtype not in [

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Skip the add/query call when the batch is empty: if not embeddings: return
  2. Fix the upstream chunking/reading step that produced zero items
  3. Validate input documents before embedding to avoid paying for embeddings that get rejected anyway

Example fix

# before
collection.add(ids=ids, embeddings=embeds)  # embeds == []

# after
if ids:
    collection.add(ids=ids, embeddings=embeds)
Defensive patterns

Strategy: validation

Validate before calling

def assert_non_empty_batch(ids, embeddings, documents=None):
    if not ids or not embeddings:
        raise ValueError("refusing to call add() with an empty batch")

if ids and embeddings:
    collection.add(ids=ids, embeddings=embeddings, documents=documents)

Type guard

def is_non_empty_embeddings(v) -> bool:
    return isinstance(v, (list,)) and len(v) > 0  # ndarray case: len(v) > 0 works for 2-D too

Try / catch

try:
    collection.add(ids=ids, embeddings=embeds, documents=docs)
except ValueError as e:
    if "at least one item" in str(e):
        logger.warning("skipped empty embedding batch")
    else:
        raise

Prevention

When it happens

Trigger: collection.add(ids=[], embeddings=[]) or collection.query(query_embeddings=[]) — an upstream batch/text list was empty, e.g. chunking produced 0 chunks, a file read returned no lines, or an empty batch loop iterated once.

Common situations: Batch ingestion pipelines that don't skip empty batches; processing small/empty documents with a chunker that emits nothing; guard code missing around 'for each file: add(chunks)'.

Related errors


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