chroma-core/chroma · error · ValueError
Expected metadata list value for key '{key}' to be non-empty
Error message
Expected metadata list value for key '{key}' to be non-empty What it means
Chroma accepts list-valued metadata (e.g. {'tags': ['a','b']}) but the list must be non-empty: an empty list carries no filterable value and the storage layer cannot represent it. _validate_metadata_list_value (chromadb/api/types.py:1047) raises when the value is []. Note the asymmetry: scalar metadata values may be None, but list values may not be empty - use None to mean 'no value'.
Source
Thrown at chromadb/api/types.py:1053
)
else:
examples = []
for idx, dup in enumerate(dups):
examples.append(dup)
if idx == 10:
break
example_string = (
f"{', '.join(examples[:5])}, ..., {', '.join(examples[-5:])}"
)
message = f"Expected IDs to be unique, found {n_dups} duplicated IDs: {example_string}"
raise errors.DuplicateIDError(message)
return ids
def _validate_metadata_list_value(key: str, value: list) -> None:
"""Validates a list metadata value: must be non-empty and homogeneously typed."""
if len(value) == 0:
raise ValueError(
f"Expected metadata list value for key '{key}' to be non-empty"
)
first_type = type(value[0])
# Normalize: bool must be checked before int since isinstance(True, int) is True
if isinstance(value[0], bool):
first_type = bool
for item in value:
item_type = bool if isinstance(item, bool) else type(item)
if item_type is not first_type or item_type not in (str, int, float, bool):
raise ValueError(
f"Expected metadata list value for key '{key}' to contain only str, int, float, or bool "
f"and all elements must be the same type, got {value}"
)
def validate_metadata(metadata: Metadata) -> Metadata:
"""Validates metadata to ensure it is a dictionary of strings to strings, ints, floats, bools, SparseVectors, or lists thereof"""
if not isinstance(metadata, dict) and metadata is not None:View on GitHub (pinned to aecdd12c8a)
Solutions
- Use None instead of [] for 'no value': {'tags': None} is valid metadata
- Strip empty lists before sending: {k: v for k, v in meta.items() if v != []}
- In ETL, map empty iterables to None at the metadata-building step
Example fix
# before
meta = {'tags': [t for t in row['tags'] if keep(t)]} # may be []
# after
meta = {'tags': [t for t in row['tags'] if keep(t)] or None} Defensive patterns
Strategy: validation
Validate before calling
def clean_empty_lists(meta):
return {k: (None if isinstance(v, list) and len(v) == 0 else v) for k, v in meta.items()}
metadatas = [clean_empty_lists(m) for m in metadatas] Type guard
def has_no_empty_list_values(meta) -> bool:
return not any(isinstance(v, list) and len(v) == 0 for v in meta.values()) Try / catch
try:
collection.add(ids=ids, metadatas=metas)
except ValueError as e:
if 'to be non-empty' in str(e):
metas = [clean_empty_lists(m) for m in metas]
collection.add(ids=ids, metadatas=metas)
else:
raise Prevention
- Represent 'no value' lists as None, never []
- Map empty iterables to None during ETL metadata building
- Unit-test metadata builders against rows with missing list fields
When it happens
Trigger: collection.add(..., metadatas=[{'tags': []}]); collection.modify(metadata={'topics': []}); collection.update(ids=..., metadatas=[{'tags': []}]) - typically tag/genre/category fields where some records legitimately have no entries.
Common situations: Tag or genre columns where empty means 'none'; ETL that defaults missing lists to [] instead of None; user profiles with empty follower/interest lists from JSON sources.
Related errors
- Expected metadata list value for key '{key}' to contain only
- Expected metadata to be a dict or None, got {type(metadata).
- Expected metadata to be a non-empty dict, got {len(metadata)
- Expected metadata to not contain the reserved key {META_KEY_
- Expected metadata key to be a str, got {key} which is a {typ
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/d14ba6fc4680fd69.
Report an issue: GitHub.