redis/redis-py · error · DataError

if XPENDING is provided with idle time or consumername, it m

Error message

if XPENDING is provided with idle time or consumername, it must be provided with min, max and count parameters

What it means

Raised by xpending_range() when min, max, and count are ALL None (summary mode) but idle or consumername is also supplied. Filters are meaningless without a range, so the client rejects the combination. Check at core.py:7766-7772 uses the set trick `{min,max,count} == {None}`.

Source

Thrown at redis/commands/core.py:7768

        count: int,
        consumername: ConsumerT | None = None,
        idle: int | None = None,
    ) -> XPendingRangeResponse | Awaitable[XPendingRangeResponse]:
        """
        Returns information about pending messages, in a range.

        name: name of the stream.
        groupname: name of the consumer group.
        idle: available from  version 6.2. filter entries by their
        idle-time, given in milliseconds (optional).
        min: minimum stream ID.
        max: maximum stream ID.
        count: number of messages to return
        consumername: name of a consumer to filter by (optional).
        """
        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:

View on GitHub (pinned to da03cdc7e8)

Solutions

  1. For a filtered/paginated result, supply all of min, max, count.
  2. For the summary (no range), drop idle and consumername and call xpending(name, group) directly.
  3. Decide up front which XPENDING form you want - summary OR range, not a mix.

Example fix

# before
r.xpending_range('s','g', None, None, None, idle=5000)
# after - pick one:
r.xpending_range('s','g', '-', '+', 10, idle=5000)   # range form
# or
r.xpending('s','g')                                   # summary form
Defensive patterns

Strategy: validation

Validate before calling

if min is max is count is None:
    if idle is not None or consumername is not None:
        raise ValueError('idle/consumername require min,max,count')
    r.xpending(name, group)
else:
    r.xpending_range(name, group, min, max, count, consumername=consumername, idle=idle)

Try / catch

from redis.exceptions import DataError
try:
    r.xpending_range(name, group, min, max, count, idle=idle, consumername=cn)
except DataError:
    r.xpending(name, group)  # fall back to summary

Prevention

When it happens

Trigger: r.xpending_range('s','g', None, None, None, idle=5000) or xpending_range('s','g',None,None,None, consumername='c1'). All three of min/max/count must be None for this branch (partial-None hits [338] instead).

Common situations: Calling xpending_range intending the summary form (xpending) but tacking on an idle filter; passing None positionals explicitly then a filter kwarg.

Related errors


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