redis/redis-py · error · DataError
XAUTOCLAIM min_idle_time must be a nonnegative integer
Error message
XAUTOCLAIM min_idle_time must be a nonnegative integer
What it means
Raised by xautoclaim() when min_idle_time, after int() coercion, is negative. CAUTION: the guard is wrapped in try/except TypeError, so values int() cannot parse (None, lists, etc.) are SWALLOWED and forwarded to Redis - only a successfully-parsed negative trips this. This is stricter than xclaim, which uses isinstance.
Source
Thrown at redis/commands/core.py:7194
criteria. Conceptually, equivalent to calling XPENDING and then XCLAIM,
but provides a more straightforward way to deal with message delivery
failures via SCAN-like semantics.
name: name of the stream.
groupname: name of the consumer group.
consumername: name of a consumer that claims the message.
min_idle_time: filter messages that were idle less than this amount of
milliseconds.
start_id: filter messages with equal or greater ID.
count: optional integer, upper limit of the number of entries that the
command attempts to claim. Set to 100 by default.
justid: optional boolean, false by default. Return just an array of IDs
of messages successfully claimed, without returning the actual message
For more information, see https://redis.io/commands/xautoclaim
"""
try:
if int(min_idle_time) < 0:
raise DataError(
"XAUTOCLAIM min_idle_time must be a nonnegative integer"
)
except TypeError:
pass
kwargs = {}
pieces = [name, groupname, consumername, min_idle_time, start_id]
try:
if int(count) < 0:
raise DataError("XPENDING count must be a integer >= 0")
pieces.extend([b"COUNT", count])
except TypeError:
pass
if justid:
pieces.append(b"JUSTID")
kwargs["parse_justid"] = True
View on GitHub (pinned to da03cdc7e8)
Solutions
- Pass 0 (not negative) when you want no idle filtering.
- Clamp upstream: min_idle_time = max(0, int(value)).
- Do not rely on this guard to catch non-numeric junk - validate the type yourself.
Example fix
# before
r.xautoclaim('s','g','c', min_idle_time=delta_ms) # delta_ms < 0
# after
r.xautoclaim('s','g','c', min_idle_time=max(0, int(delta_ms))) Defensive patterns
Strategy: validation
Validate before calling
idle = max(0, int(min_idle_time)) if min_idle_time is not None else 0 r.xautoclaim(name, group, consumer, idle)
Try / catch
from redis.exceptions import DataError
try:
r.xautoclaim(name, group, consumer, ms)
except DataError:
r.xautoclaim(name, group, consumer, max(0, int(ms))) Prevention
- Use 0 for 'claim anything idle', never a negative sentinel.
- Pre-validate the type; the library's try/except silently passes non-int-coercible values.
When it happens
Trigger: xautoclaim(name, group, consumer, min_idle_time=-1) or ='-1' (int('-1') == -1). Passing min_idle_time=None or ='abc' does NOT raise here - it slips through to the server.
Common situations: Computing idle from a clock-skewed delta that went negative; using -1 as a 'no filter' sentinel; passing a float like 5.5 (int() truncates to 5, ok) - but a negative float truncates to a negative int and trips.
Related errors
- XPENDING count must be a integer >= 0
- XNACK retrycount must be >= 0
- XPENDING idle must be a integer >= 0
- XCFGSET idmp_duration must be an integer between 1 and 300
- XCFGSET idmp_maxsize must be an integer between 1 and 1,000,
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/e343dfd927e68ffb.json.
Report an issue: GitHub.