redis/redis-py · error · DataError
XRANGE count must be a positive integer
Error message
XRANGE count must be a positive integer
What it means
Raised by RedisClient xrange() (redis/commands/core.py:7845) as a DataError when the count argument is present but is not a Python int or is less than 1. The library validates client-side before sending the XRANGE command so an invalid COUNT never reaches the server. Note bool is a subclass of int so True/False slip through; floats, strings, and zero/negative ints are rejected.
Solutions
- Pass an int >= 1 for count, or pass None / omit it when you want no limit.
- Coerce untrusted input: count = int(count) and guard count is not None and count >= 1 before calling.
- If you meant 'all entries', do not set count at all - None means unlimited.
Example fix
# before
client.xrange('mystream', '-', '+', count=os.environ['XRANGE_COUNT'])
# after
c = int(os.environ['XRANGE_COUNT'])
client.xrange('mystream', '-', '+', count=c if c >= 1 else None) Defensive patterns
Strategy: validation
Validate before calling
def safe_xrange_count(count):
if count is None:
return None
if not isinstance(count, int) or isinstance(count, bool) or count < 1:
raise DataError('XRANGE count must be a positive int')
return count Type guard
from typing import Union
def is_valid_xrange_count(c) -> bool:
return isinstance(c, int) and not isinstance(c, bool) and c >= 1 Try / catch
from redis.exceptions import DataError
try:
client.xrange('s', '-', '+', count=user_count)
except DataError as e:
if 'XRANGE count' in str(e):
logger.warning('invalid count %r, retrying unlimited', user_count)
client.xrange('s', '-', '+')
else:
raise Prevention
- Always coerce env/config values to int before passing as count.
- Treat count=0 as None (unlimited), since 0 is invalid.
- Unit-test stream helpers with 0, negative, float, and string inputs.
When it happens
Trigger: Calling client.xrange(name, '-', '+', count=0), count=-5, count=1.5, count='10', or count=None-equivalent truthy non-int. Any non-int or count<1 value passed as the count kwarg triggers it.
Common situations: Reading count from untyped config/env (os.environ returns str), passing a float from a computed ratio without int(), defaulting count to 0 meaning 'no limit' (0 is invalid; use None), or off-by-one when paginating streams.
Related errors
- XREAD block must be a non-negative integer
- XREAD count must be a positive integer
- XREAD max_count must be a positive integer
- Invalid FPHA type: . Must be one of
- No key specified
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/24924b8a8d482a8c.
Report an issue: GitHub.
Appendix: source
Thrown at redis/commands/core.py:7845
Read stream values within an interval.
name: name of the stream.
start: first stream ID. defaults to '-',
meaning the earliest available.
finish: last stream ID. defaults to '+',
meaning the latest available.
count: if set, only return this many items, beginning with the
earliest available.
For more information, see https://redis.io/commands/xrange
"""
pieces = [min, max]
if count is not None:
if not isinstance(count, int) or count < 1:
raise DataError("XRANGE count must be a positive integer")
pieces.append(b"COUNT")
pieces.append(str(count))
return self.execute_command("XRANGE", name, *pieces, keys=[name])
@overload
def xread(
self: SyncClientProtocol,
streams: Dict[KeyT, StreamIdT],
count: int | None = None,
block: int | None = None,
max_count: int | None = None,
max_size: int | None = None,
) -> XReadResponse: ...
@overload
def xread(
self: AsyncClientProtocol,View on GitHub (pinned to 6a6b581b48)