redis/redis-py · error · DataError

XPENDING count must be a integer >= 0

Error message

XPENDING count must be a integer >= 0

What it means

Raised by xautoclaim() for its `count` argument - but the MESSAGE text says 'XPENDING count', a copy-paste artifact from the sibling xpending_range code. It fires when int(count) is negative. Same try/except TypeError pattern as min_idle_time: non-coercible counts are swallowed and sent to Redis.

Source

Thrown at redis/commands/core.py:7205

        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

        return self.execute_command("XAUTOCLAIM", *pieces, **kwargs)

    @overload
    def xclaim(
        self: SyncClientProtocol,
        name: KeyT,
        groupname: GroupT,
        consumername: ConsumerT,
        min_idle_time: int,
        message_ids: Union[List[StreamIdT], Tuple[StreamIdT]],
        idle: int | None = None,

View on GitHub (pinned to da03cdc7e8)

Solutions

  1. Recognize the message is misleading - audit your xautoclaim(...) count argument, not xpending.
  2. Pass count=None (omit) or a non-negative int.
  3. Clamp: count = None if raw is None else max(0, int(raw)).

Example fix

# before
r.xautoclaim('s','g','c', 5000, count=limit)  # limit == -1
# after
r.xautoclaim('s','g','c', 5000, count=max(0, int(limit)))
Defensive patterns

Strategy: validation

Validate before calling

count = None if raw_count is None else max(0, int(raw_count))
r.xautoclaim(name, group, consumer, min_idle, count=count)

Try / catch

from redis.exceptions import DataError
try:
    r.xautoclaim(name, group, consumer, ms, count=c)
except DataError as e:
    # message says 'XPENDING' but this is xautoclaim's count
    c = max(0, int(c)); r.xautoclaim(name, group, consumer, ms, count=c)

Prevention

When it happens

Trigger: xautoclaim(name, group, consumer, min_idle, count=-5) or count='-5'. count=None or count='abc' does NOT raise here. Check at core.py:7203-7208.

Common situations: Reusing a variable named for XPENDING; a count derived from a subtraction that underflowed; misled by the message into thinking xpending was the culprit when the failing call is xautoclaim.

Related errors


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