chroma-core/chroma · error · ValueError
Expected metadata key to be a str, got {key}
Error message
Expected metadata key to be a str, got {key} What it means
Update-path metadata keys must be str, enforced by validate_update_metadata (chromadb/api/types.py:1117) on collection.update. It raises a ValueError here, whereas the insert-path twin raises TypeError - worth knowing if you catch exceptions by type. Numeric or other non-str keys from dict(zip(...)), numeric-keyed YAML, or programmatically built dicts trigger it.
Source
Thrown at chromadb/api/types.py:1117
raise ValueError(
f"Expected metadata value to be a str, int, float, bool, SparseVector, list, or None, got {value} which is a {type(value).__name__}"
)
return metadata
def validate_update_metadata(metadata: UpdateMetadata) -> UpdateMetadata:
"""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:
raise ValueError(
f"Expected metadata to be a dict or None, got {type(metadata)}"
)
if metadata is None:
return metadata
if len(metadata) == 0:
raise ValueError(f"Expected metadata to be a non-empty dict, got {metadata}")
for key, value in metadata.items():
if not isinstance(key, str):
raise ValueError(f"Expected metadata key to be a str, got {key}")
# Check if value is a SparseVector (validation happens in __post_init__)
if isinstance(value, SparseVector):
pass # Already validated in SparseVector.__post_init__
elif isinstance(value, list):
_validate_metadata_list_value(key, value)
# isinstance(True, int) evaluates to True, so we need to check for bools separately
elif not isinstance(value, bool) and not isinstance(
value, (str, int, float, type(None))
):
raise ValueError(
f"Expected metadata value to be a str, int, float, bool, SparseVector, list, or None, got {value}"
)
return metadata
def serialize_metadata(metadata: Optional[Metadata]) -> Optional[Dict[str, Any]]:
"""Serialize metadata for transport, converting SparseVector dataclass instances to dicts.
View on GitHub (pinned to aecdd12c8a)
Solutions
- Stringify keys when building the update dict: {str(k): v for k, v in meta.items()}
- Catch ValueError (not TypeError) around update() in defensive wrappers
- Keep metadata schemas keyed by strings from the start
Example fix
# before
patch = dict(zip(field_codes, new_values)) # {101: 'x'}
# after
patch = {str(k): v for k, v in zip(field_codes, new_values)} Defensive patterns
Strategy: type-guard
Validate before calling
patch = {str(k) if not isinstance(k, str) else k: v for k, v in patch.items()}
collection.update(ids=ids, metadatas=[patch]) Type guard
def update_metadata_keys_are_str(meta) -> bool:
return all(isinstance(k, str) for k in meta) Try / catch
try:
collection.update(ids=ids, metadatas=metas)
except ValueError as e: # update path raises ValueError, insert path TypeError
if 'Expected metadata key to be a str' in str(e):
collection.update(ids=ids, metadatas=[{str(k): v for k, v in m.items()} for m in metas])
else:
raise Prevention
- Stringify keys when building update patches from numeric mappings
- Remember the insert twin raises TypeError while update raises ValueError
- Keep metadata schemas string-keyed from the start
When it happens
Trigger: collection.update(ids=..., metadatas=[{1: 'a'}]); metadata dicts built with enumerate() integers as keys; YAML-parsed configs where '1:' becomes an int key; id-to-value maps misused directly as metadata.
Common situations: Programmatically built update dicts; mappings from numeric codes to values; lenient parsers preserving numeric key types.
Related errors
- Expected metadata key to be a str, got {key} which is a {typ
- Expected metadata to be a dict or None, got {type(metadata)}
- Expected metadata to be a non-empty dict, got {metadata}
- Expected metadata value to be a str, int, float, bool, Spars
- Expected metadata list value for key '{key}' to be non-empty
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/3673b6ae42dcd4fe.
Report an issue: GitHub.