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

  1. Keep only {'offset', 'limit'} in the dict.
  2. Rename legacy names during migration: n_results -> limit.
  3. 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

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


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