chroma-core/chroma · error · ValueError
Unexpected keys in Limit dict: {unexpected_keys}
Error message
Unexpected keys in Limit dict: {unexpected_keys} What it means
Limit.from_dict applies closed-schema validation: only 'offset' and 'limit' are accepted, and any extra key raises ValueError listing the offending set. This catches typos and API mix-ups early instead of silently ignoring unknown settings.
Source
Thrown at chromadb/execution/expression/operator.py:590
f"Limit offset must be an integer, got {type(offset).__name__}"
)
if offset < 0:
raise ValueError(f"Limit offset must be non-negative, got {offset}")
limit = data.get("limit")
if limit is not None:
if not isinstance(limit, int):
raise TypeError(
f"Limit limit must be an integer, got {type(limit).__name__}"
)
if limit <= 0:
raise ValueError(f"Limit limit must be positive, got {limit}")
# Check for unexpected keys
allowed_keys = {"offset", "limit"}
unexpected_keys = set(data.keys()) - allowed_keys
if unexpected_keys:
raise ValueError(f"Unexpected keys in Limit dict: {unexpected_keys}")
return Limit(offset=offset, limit=limit)
@dataclass
class Projection:
document: bool = False
embedding: bool = False
metadata: bool = False
rank: bool = False
uri: bool = False
@property
def included(self) -> Include:
includes = list()
if self.document:
includes.append("documents")
if self.embedding:View on GitHub (pinned to aecdd12c8a)
Solutions
- Keep only {'offset', 'limit'} in the dict.
- Rename legacy names during migration: n_results -> limit.
- Whitelist keys at your boundary, rejecting extras with your own 400 error.
Example fix
# before
Search(limit={'n_results': 10, 'offset': 0}) # -> ValueError: Unexpected keys
# after
Search(limit={'limit': 10, 'offset': 0}) Defensive patterns
Strategy: validation
Validate before calling
ALLOWED_LIMIT_KEYS = {'offset', 'limit'}
def sanitize_limit(data: dict) -> dict:
extra = set(data) - ALLOWED_LIMIT_KEYS
if extra:
raise ValueError(f'unsupported limit keys: {sorted(extra)}')
return data Prevention
- Map external field names (e.g. n_results) to offset/limit explicitly instead of forwarding raw payloads.
- Use a typed schema for paging params at the edge.
- Watch for '$'-prefixed keys leaking in from where/rank expressions.
When it happens
Trigger: Limit.from_dict({'limit': 10, 'page_size': 2}); carrying over the classic kwarg name {'n_results': 10}; typos like {'offsett': 0}; operator-style keys like {'$limit': 10} leaking in from expression dicts.
Common situations: Migrating from collection.query(n_results=...) and reusing the old field name; forwarding raw user JSON into Search(limit=...); shared config blocks where unrelated keys ride along.
Related errors
- Limit offset must be non-negative, got {offset}
- Limit limit must be positive, got {limit}
- Bad request to ${input} with status: ${resp.statusText}
- You must provide either queryEmbeddings or queryTexts
- Expected dict for Limit, got {type(data).__name__}
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/7b850a2db4cb2c2a.
Report an issue: GitHub.