redis/redis-py · error · DataError

XREAD count must be a positive integer

Error message

XREAD count must be a positive integer

What it means

Raised by xread() when the per-stream count argument is not an int or is less than 1. count caps entries returned per stream; the library enforces int >= 1 client-side. Strict isinstance(count, int) check — strings and floats are rejected.

Source

Thrown at redis/commands/core.py:7913

        max_size: if set, a soft cap on the total server reply size in bytes
                  across all streams combined. Measured server-side including
                  protocol overhead, so it is not an exact application-payload
                  size guarantee; a single available entry larger than the cap
                  may still be returned. Must be a positive integer. Requires
                  Redis >= 8.10.0.

        For more information, see https://redis.io/commands/xread
        """
        pieces = []
        if block is not None:
            if not isinstance(block, int) or block < 0:
                raise DataError("XREAD block must be a non-negative integer")
            pieces.append(b"BLOCK")
            pieces.append(str(block))
        if count is not None:
            if not isinstance(count, int) or count < 1:
                raise DataError("XREAD count must be a positive integer")
            pieces.append(b"COUNT")
            pieces.append(str(count))
        if max_count is not None:
            if not isinstance(max_count, int) or max_count < 1:
                raise DataError("XREAD max_count must be a positive integer")
            if count is not None and max_count < count:
                raise DataError(
                    "XREAD max_count must be greater than or equal to count"
                )
            pieces.append(b"MAXCOUNT")
            pieces.append(str(max_count))
        if max_size is not None:
            if not isinstance(max_size, int) or max_size < 1:
                raise DataError("XREAD max_size must be a positive integer")
            pieces.append(b"MAXSIZE")
            pieces.append(str(max_size))
        if not isinstance(streams, dict) or len(streams) == 0:
            raise DataError("XREAD streams must be a non empty dict")

View on GitHub (pinned to da03cdc7e8)

Solutions

  1. Pass an int >= 1, or None for no per-stream limit.
  2. Coerce explicitly: count = int(count) if count else None.
  3. Remember count is per-stream; for a cumulative cap use max_count (Redis >= 8.10.0).

Example fix

// before
client.xread({"s": "0"}, count=10.0)
// after
client.xread({"s": "0"}, count=10)
Defensive patterns

Strategy: validation

Validate before calling

def normalize_count(v):
    if v is None:
        return None
    if not isinstance(v, int) or isinstance(v, bool):
        raise TypeError(f"count must be int, got {type(v)}")
    if v < 1:
        raise ValueError(f"count must be >= 1, got {v}")
    return v

count = normalize_count(count)
client.xread({"s": "0"}, count=count)

Type guard

def is_positive_int(v) -> bool:
    return isinstance(v, int) and not isinstance(v, bool) and v >= 1

Try / catch

from redis.exceptions import DataError
try:
    client.xread({"s": "0"}, count=count)
except DataError as e:
    if "XREAD count" in str(e):
        client.xread({"s": "0"}, count=int(count))
    else:
        raise

Prevention

When it happens

Trigger: Call client.xread(streams, count=...) with count as a float, string, zero, negative number, or non-int. Pass None or omit for no per-stream cap.

Common situations: Reusing a count variable that also feeds max_count; reading count from a config file as string; passing 0 to mean 'none'.

Related errors


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