redis/redis-py · error · DataError

XPENDING idle must be a integer >= 0

Error message

XPENDING idle must be a integer >= 0

What it means

Raised by xpending_range() when idle, after int() coercion, is negative. Same try/except TypeError pattern as xautoclaim: non-coercible idle values are SWALLOWED and forwarded to Redis - only a successfully-parsed negative trips this. idle is only meaningful together with min/max/count (it lives after the all-None guard).

Source

Thrown at redis/commands/core.py:7784

        if {min, max, count} == {None}:
            if idle is not None or consumername is not None:
                raise DataError(
                    "if XPENDING is provided with idle time"
                    " or consumername, it must be provided"
                    " with min, max and count parameters"
                )
            return self.xpending(name, groupname)

        pieces = [name, groupname]
        if min is None or max is None or count is None:
            raise DataError(
                "XPENDING must be provided with min, max "
                "and count parameters, or none of them."
            )
        # idle
        try:
            if int(idle) < 0:
                raise DataError("XPENDING idle must be a integer >= 0")
            pieces.extend(["IDLE", idle])
        except TypeError:
            pass
        # count
        try:
            if int(count) < 0:
                raise DataError("XPENDING count must be a integer >= 0")
            pieces.extend([min, max, count])
        except TypeError:
            pass
        # consumername
        if consumername:
            pieces.append(consumername)

        return self.execute_command("XPENDING", *pieces, parse_detail=True)

    @overload
    def xrange(

View on GitHub (pinned to da03cdc7e8)

Solutions

  1. Pass idle=None (or omit) to skip the idle filter.
  2. Pass a non-negative int ms; clamp with max(0, int(raw)).
  3. Pre-validate the type - the library's try/except silently passes non-int-coercible values.

Example fix

# before
r.xpending_range('s','g','-','+',10, idle=threshold)  # threshold < 0
# after
r.xpending_range('s','g','-','+',10, idle=None if threshold is None else max(0, int(threshold)))
Defensive patterns

Strategy: validation

Validate before calling

idle = None if idle is None else max(0, int(idle))
r.xpending_range(name, group, min, max, count, idle=idle)

Try / catch

from redis.exceptions import DataError
try:
    r.xpending_range(name, group, min, max, count, idle=idle)
except DataError:
    r.xpending_range(name, group, min, max, count, idle=max(0, int(idle)))

Prevention

When it happens

Trigger: r.xpending_range('s','g','-','+',10, idle=-1) or idle='-1'. idle=None or ='abc' does NOT raise here. Check at core.py:7782-7787.

Common situations: Computing an idle threshold from a delta that went negative due to clock skew; using -1 as 'no idle filter' (the correct way to omit is idle=None).

Related errors


AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04). Data as JSON: /data/errors/2d360aab3db0aae0.json. Report an issue: GitHub.