redis/redis-py · error · DataError
XREAD count must be a positive integer
Error message
XREAD count must be a positive integer
What it means
Raised by xread() (redis/commands/core.py:7913) as a DataError when count is not an int or is < 1. count is the per-stream COUNT limit; unlike block it must be strictly positive. Validated before the XREAD command is assembled.
Solutions
- Pass an int >= 1 for count, or None for no per-stream limit.
- In pagination, break or recompute when remaining <= 0 rather than passing 0.
- Coerce env input: count = int(val) if val else None.
Example fix
# before
remaining = total - seen
client.xread(streams, count=remaining)
# after
if remaining >= 1:
client.xread(streams, count=remaining)
else:
break Defensive patterns
Strategy: validation
Validate before calling
def safe_xread_count(count):
if count is None:
return None
if not isinstance(count, int) or isinstance(count, bool) or count < 1:
raise DataError('XREAD count must be a positive int')
return count Type guard
def is_valid_xread_count(c) -> bool:
return isinstance(c, int) and not isinstance(c, bool) and c >= 1 Try / catch
from redis.exceptions import DataError
try:
client.xread(streams, count=batch)
except DataError as e:
if 'XREAD count' in str(e):
client.xread(streams, count=100) # sane default
else:
raise Prevention
- In pagination loops, break when remaining < 1 instead of passing 0.
- Distinguish count (per-stream) from max_count (cumulative) - both must be >= 1.
- Coerce env-sourced batch sizes to int.
When it happens
Trigger: Calling client.xread(streams, count=0), count=-1, count='100', or count=50.0. count=None means no limit.
Common situations: Pagination loop that decrements count and hits 0, passing a float batch size, or env-sourced string value. Distinguishing count (per-stream limit) from max_count (cumulative cap) - both must be positive ints.
Related errors
- XREAD block must be a non-negative integer
- XREAD max_count must be a positive integer
- XRANGE 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/387fe90bbcafebf0.
Report an issue: GitHub.
Appendix: source
Thrown at redis/commands/core.py:7913
max_size: if set, a soft cap on the total server reply size in bytes
across all streams combined. Measured server-side including
protocol overhead, so it is not an exact application-payload
size guarantee; a single available entry larger than the cap
may still be returned. Must be a positive integer. Requires
Redis >= 8.10.0.
For more information, see https://redis.io/commands/xread
"""
pieces = []
if block is not None:
if not isinstance(block, int) or block < 0:
raise DataError("XREAD block must be a non-negative integer")
pieces.append(b"BLOCK")
pieces.append(str(block))
if count is not None:
if not isinstance(count, int) or count < 1:
raise DataError("XREAD count must be a positive integer")
pieces.append(b"COUNT")
pieces.append(str(count))
if max_count is not None:
if not isinstance(max_count, int) or max_count < 1:
raise DataError("XREAD max_count must be a positive integer")
if count is not None and max_count < count:
raise DataError(
"XREAD max_count must be greater than or equal to count"
)
pieces.append(b"MAXCOUNT")
pieces.append(str(max_count))
if max_size is not None:
if not isinstance(max_size, int) or max_size < 1:
raise DataError("XREAD max_size must be a positive integer")
pieces.append(b"MAXSIZE")
pieces.append(str(max_size))
if not isinstance(streams, dict) or len(streams) == 0:
raise DataError("XREAD streams must be a non empty dict")View on GitHub (pinned to 6a6b581b48)