redis/redis-py · error · DataError
XCLAIM min_idle_time must be a non negative integer
Error message
XCLAIM min_idle_time must be a non negative integer
What it means
Raised by Redis.xclaim() when min_idle_time is not an int or is negative. Unlike xautoclaim, this uses a strict isinstance(int) check, so floats and numeric strings are rejected (not just negatives). bool is a subclass of int, so True/1 pass and False/0 pass as 0.
Solutions
- Pass an int (milliseconds) >= 0.
- Coerce explicitly: min_idle_time = int(float_value) if you need rounding.
- Reject bool if it is not semantically valid for your call.
Example fix
# before
r.xclaim('s','g','c', 1.5, ['1-0'])
# after
r.xclaim('s','g','c', 2, ['1-0']) Defensive patterns
Strategy: type-guard
Validate before calling
if not isinstance(min_idle_time, int) or isinstance(min_idle_time, bool) or min_idle_time < 0:
raise TypeError('min_idle_time must be a non-negative int') Type guard
lambda v: isinstance(v, int) and not isinstance(v, bool) and v >= 0
Try / catch
from redis.exceptions import DataError
try:
r.xclaim('s','g','c', ms, ids)
except DataError as e:
log.warning('bad xclaim min_idle_time %r: %s', ms, e) Prevention
- Keep min_idle_time as an int throughout your pipeline.
- xclaim's type check is stricter than xautoclaim's; do not assume the same value passes both.
When it happens
Trigger: Calling r.xclaim(name, group, consumer, min_idle_time, ids) with min_idle_time as a float (1.5), a string ('100'), None (fails isinstance), or a negative int (-1).
Common situations: Passing a float ms value, reading idle from config as a string, or a sign error.
Related errors
- XCLAIM idle must be an integer
- XCLAIM retrycount must be an integer
- XCLAIM time must be an integer
- XCLAIM force must be a boolean
- XCLAIM justid must be a boolean
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/3f5f2e7f5aa9db33.
Report an issue: GitHub.
Appendix: source
Thrown at redis/commands/core.py:7293
time: optional integer. This is the same as idle but instead of a
relative amount of milliseconds, it sets the idle time to a specific
Unix time (in milliseconds).
retrycount: optional integer. set the retry counter to the specified
value. This counter is incremented every time a message is delivered
again.
force: optional boolean, false by default. Creates the pending message
entry in the PEL even if certain specified IDs are not already in the
PEL assigned to a different client.
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/xclaim
"""
if not isinstance(min_idle_time, int) or min_idle_time < 0:
raise DataError("XCLAIM min_idle_time must be a non negative integer")
if not isinstance(message_ids, (list, tuple)) or not message_ids:
raise DataError(
"XCLAIM message_ids must be a non empty list or "
"tuple of message IDs to claim"
)
kwargs = {}
pieces: list[EncodableT] = [name, groupname, consumername, str(min_idle_time)]
pieces.extend(list(message_ids))
if idle is not None:
if not isinstance(idle, int):
raise DataError("XCLAIM idle must be an integer")
pieces.extend((b"IDLE", str(idle)))
if time is not None:
if not isinstance(time, int):
raise DataError("XCLAIM time must be an integer")
pieces.extend((b"TIME", str(time)))View on GitHub (pinned to 6a6b581b48)