redis/redis-py · error · DataError
XADD maxlen must be non-negative integer
Error message
XADD maxlen must be non-negative integer
What it means
Raised by xadd() when maxlen is provided but is not a non-negative int. MAXLEN requires a non-negative integer count; bools, floats, negatives, or string-encoded numbers are rejected because the library appends str(maxlen) directly into the command and validates type to prevent malformed commands.
Source
Thrown at redis/commands/core.py:7041
if ref_policy is not None and ref_policy not in {"KEEPREF", "DELREF", "ACKED"}:
raise DataError("XADD ref_policy must be one of: KEEPREF, DELREF, ACKED")
if nomkstream:
pieces.append(b"NOMKSTREAM")
if ref_policy is not None:
pieces.append(ref_policy)
if idmpauto is not None:
pieces.extend([b"IDMPAUTO", idmpauto])
if idmp is not None:
if not isinstance(idmp, tuple) or len(idmp) != 2:
raise DataError(
"XADD idmp must be a tuple of (producer_id, idempotent_id)"
)
pieces.extend([b"IDMP", idmp[0], idmp[1]])
if maxlen is not None:
if not isinstance(maxlen, int) or maxlen < 0:
raise DataError("XADD maxlen must be non-negative integer")
pieces.append(b"MAXLEN")
if approximate:
pieces.append(b"~")
pieces.append(str(maxlen))
if minid is not None:
pieces.append(b"MINID")
if approximate:
pieces.append(b"~")
pieces.append(minid)
if limit is not None:
pieces.extend([b"LIMIT", limit])
pieces.append(id)
if not isinstance(fields, dict) or len(fields) == 0:
raise DataError("XADD fields must be a non-empty dict")
for pair in fields.items():
pieces.extend(pair)
return self.execute_command("XADD", name, *pieces)
View on GitHub (pinned to da03cdc7e8)
Solutions
- Pass maxlen as a non-negative int, e.g. maxlen=1000.
- Coerce/validate config values with int() and a >= 0 check before calling.
- Use 0 only if you intend to trim everything (semantics may differ; prefer minid for that).
Example fix
# before
await r.xadd('s', {'f':'v'}, maxlen='1000')
# after
await r.xadd('s', {'f':'v'}, maxlen=1000) Defensive patterns
Strategy: type-guard
Validate before calling
def validate_maxlen(maxlen):
if maxlen is not None and (not isinstance(maxlen, int) or isinstance(maxlen, bool) or maxlen < 0):
raise ValueError('maxlen must be a non-negative integer')
return True Type guard
def is_valid_maxlen(m) -> bool:
return m is None or (isinstance(m, int) and not isinstance(m, bool) and m >= 0) Prevention
- Pass maxlen as a non-negative int (not a string or float).
- Coerce config values with int() and a >= 0 guard before calling.
- Remember bool is a subclass of int in Python; exclude it explicitly.
When it happens
Trigger: Calling client.xadd(name, fields, maxlen=-1), maxlen=10.5, maxlen='1000', or maxlen=True.
Common situations: Passing a config value loaded as a string; computing maxlen from a float expression; off-by-one producing a negative; passing a bool by mistake.
Related errors
- Only one of ```maxlen``` or ```minid``` may be specified
- Only one of ```idmpauto``` or ```idmp``` may be specified
- IDMPAUTO and IDMP can only be used with id='*'
- XADD ref_policy must be one of: KEEPREF, DELREF, ACKED
- XADD idmp must be a tuple of (producer_id, idempotent_id)
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/02b0ef858b772d4d.json.
Report an issue: GitHub.