chroma-core/chroma · error · ValueError
Expected IDs to be a non-empty list, got {len(ids)} IDs
Error message
Expected IDs to be a non-empty list, got {len(ids)} IDs What it means
validate_ids rejects an empty ids list: adding, upserting or updating zero records is meaningless and almost always signals an upstream bug such as an empty dataframe or a fully filtered-out batch. Note that through collection.add()/upsert()/update() an empty ids list is caught slightly earlier by the record-set length check ('Non-empty lists are required'); the classic 'Expected IDs to be a non-empty list' message appears when validate_ids is invoked directly.
Source
Thrown at chromadb/api/types.py:1019
if not function_signature == protocol_signature:
raise ValueError(
f"Expected EmbeddingFunction.__call__ to have the following signature: {protocol_signature}, got {function_signature}\n"
"Please see https://docs.trychroma.com/guides/embeddings for details of the EmbeddingFunction interface.\n"
"Please note the recent change to the EmbeddingFunction interface: https://docs.trychroma.com/deployment/migration#migration-to-0.4.16---november-7,-2023 \n"
)
class DataLoader(Protocol[L]):
def __call__(self, uris: URIs) -> L:
...
def validate_ids(ids: IDs) -> IDs:
"""Validates ids to ensure it is a list of strings"""
if not isinstance(ids, list):
raise ValueError(f"Expected IDs to be a list, got {type(ids).__name__} as IDs")
if len(ids) == 0:
raise ValueError(f"Expected IDs to be a non-empty list, got {len(ids)} IDs")
seen = set()
dups = set()
for id_ in ids:
if not isinstance(id_, str):
raise ValueError(f"Expected ID to be a str, got {id_}")
if id_ in seen:
dups.add(id_)
else:
seen.add(id_)
if dups:
n_dups = len(dups)
if n_dups < 10:
example_string = ", ".join(dups)
message = (
f"Expected IDs to be unique, found duplicates of: {example_string}"
)
else:
examples = []View on GitHub (pinned to aecdd12c8a)
Solutions
- Skip the call when the batch is empty: 'if not ids: continue' or 'return'
- Log a warning or counter when a batch is empty so silent upstream bugs surface
- Fix the upstream producer if empty batches are unexpected
Example fix
# before
collection.add(ids=ids, documents=docs) # ids can be []
# after
if ids:
collection.add(ids=ids, documents=docs) Defensive patterns
Strategy: validation
Validate before calling
if not ids:
logger.info('empty batch, skipping')
return
collection.add(ids=ids, documents=docs) Type guard
def is_nonempty_ids(ids) -> bool:
return isinstance(ids, list) and len(ids) > 0 Try / catch
try:
collection.add(ids=ids, documents=docs)
except ValueError as e:
if 'non-empty list' in str(e) and not ids:
return # nothing to do
raise Prevention
- Guard every batch loop with 'if not ids: continue'
- Count and log batch sizes so zero-size batches stand out
- Fail loudly in dev when producers emit empty batches
When it happens
Trigger: Calling validate_ids([]); collection.add(ids=[], documents=[]) (raises the sibling length-consistency error first); update(ids=[]) with nothing to change; batch loops over query results that returned zero rows.
Common situations: Iterating batches from a dataframe or database cursor that produced an empty batch; filter logic that accidentally empties the batch; scheduled ingestion jobs on days with no new data.
Related errors
- Expected IDs to be a list, got {type(ids).__name__} as IDs
- Expected ID to be a str, got {id_}
- Expected 'ids' to be an array, but got ${typeof ids}
- Expected 'ids' to be a non-empty list
- Found non-string IDs at ${nonStrings.join(", ")}
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/4874c079b9041c5d.
Report an issue: GitHub.