chroma-core/chroma · error · TypeError
Limit offset must be an integer, got {type(offset).__name__}
Error message
Limit offset must be an integer, got {type(offset).__name__} What it means
Inside Limit.from_dict, the 'offset' field must be a Python int; floats and numeric strings fail isinstance(offset, int) and raise TypeError even when they look numeric (10.5, '10'). The check runs on data.get('offset', 0), so a bad value anywhere in the dict is caught before Limit is built.
Source
Thrown at chromadb/execution/expression/operator.py:571
if self.limit is not None:
result["limit"] = self.limit
return result
@staticmethod
def from_dict(data: Dict[str, Any]) -> "Limit":
"""Create Limit from dictionary.
Examples:
- {"offset": 10} -> Limit(offset=10)
- {"offset": 10, "limit": 20} -> Limit(offset=10, limit=20)
- {"limit": 20} -> Limit(offset=0, limit=20)
"""
if not isinstance(data, dict):
raise TypeError(f"Expected dict for Limit, got {type(data).__name__}")
offset = data.get("offset", 0)
if not isinstance(offset, int):
raise TypeError(
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:View on GitHub (pinned to aecdd12c8a)
Solutions
- Send a plain int: {'offset': 10}.
- Coerce known-clean values before parsing: {'offset': int(offset)} (for floats, only when value.is_integer()).
- Declare offset as an integer field in your config/pydantic schema so it arrives typed.
Example fix
# before
Search(limit={'offset': '10', 'limit': 20}) # -> TypeError: got str
# after
Search(limit={'offset': 10, 'limit': 20})
# or, for untrusted input
Search(limit={'offset': int(offset_value), 'limit': 20}) Defensive patterns
Strategy: validation
Validate before calling
def normalize_offset(data: dict) -> dict:
off = data.get('offset', 0)
if isinstance(off, bool):
raise TypeError('offset must be an int, not bool')
if isinstance(off, float) and off.is_integer():
return {**data, 'offset': int(off)}
if isinstance(off, str) and off.lstrip('-').isdigit():
return {**data, 'offset': int(off)}
return data
Search(limit=normalize_offset(limit_cfg)) Type guard
def has_valid_offset(data) -> bool:
off = data.get('offset', 0) if isinstance(data, dict) else None
return isinstance(off, int) and not isinstance(off, bool) Prevention
- Keep pagination arithmetic in ints (use // instead of /).
- Declare offset as an integer field in config schemas so it arrives typed.
- Unit-test offset boundaries (0, 1, large) in one shared helper.
When it happens
Trigger: Limit.from_dict({'offset': 10.5}); Search(limit={'offset': '10'}); pagination math that mixes in a float, e.g. {'offset': int(size * (page - 1.0))} before the cast.
Common situations: Computed offsets using float arithmetic; YAML values parsed as strings ('10'); strict JSON decoders that return 10.0 for every number; form fields arriving as strings.
Related errors
- Expected dict for Limit, got {type(data).__name__}
- Limit offset must be non-negative, got {offset}
- Limit limit must be an integer, got {type(limit).__name__}
- Limit limit must be positive, got {limit}
- Unexpected keys in Limit dict: {unexpected_keys}
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/f775c05d1bf379e4.
Report an issue: GitHub.