redis/redis-py · error · DataError
XADD idmp must be a tuple of (producer_id, idempotent_id)
Error message
XADD idmp must be a tuple of (producer_id, idempotent_id)
What it means
Raised by xadd() when idmp is provided but is not a 2-element tuple. idmp must be a (producer_id, idempotent_id) pair where producer_id is a str and idempotent_id is bytes; the library destructures idmp[0] and idmp[1] when building the IDMP command clause.
Source
Thrown at redis/commands/core.py:7035
if idmpauto is not None and idmp is not None:
raise DataError("Only one of ```idmpauto``` or ```idmp``` may be specified")
if (idmpauto is not None or idmp is not None) and id != "*":
raise DataError("IDMPAUTO and IDMP can only be used with id='*'")
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)View on GitHub (pinned to da03cdc7e8)
Solutions
- Pass idmp as a 2-tuple: idmp=('producer-1', b'idempotent-id').
- Ensure the second element is bytes (the idempotent ID).
- If you only have a producer ID, use idmpauto instead.
Example fix
# before
await r.xadd('s', {'f':'v'}, id='*', idmp='prod-1')
# after
await r.xadd('s', {'f':'v'}, id='*', idmp=('prod-1', b'abc123')) Defensive patterns
Strategy: type-guard
Validate before calling
def validate_idmp(idmp):
if idmp is not None and (not isinstance(idmp, tuple) or len(idmp) != 2):
raise ValueError('idmp must be a (producer_id, idempotent_id) tuple')
return True Type guard
def is_valid_idmp(idmp) -> bool:
return idmp is None or (isinstance(idmp, tuple) and len(idmp) == 2) Prevention
- Pass idmp as a 2-tuple: ('producer-id', b'idempotent-id').
- Use idmpauto if you only have a producer ID.
- Do not pass a list, string, or single value for idmp.
When it happens
Trigger: Calling client.xadd(name, fields, id='*', idmp='prod-1'), idmp=['p1', b'x'] (list not tuple), or idmp=('p1',) (single element).
Common situations: Passing a list instead of a tuple; passing only a producer ID; passing a flat string; misreading the type hint.
Related errors
- Only one of ```idmpauto``` or ```idmp``` may be specified
- IDMPAUTO and IDMP can only be used with id='*'
- Only one of ```maxlen``` or ```minid``` may be specified
- XADD ref_policy must be one of: KEEPREF, DELREF, ACKED
- XADD maxlen must be non-negative integer
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/518c0b8fc66acd8d.json.
Report an issue: GitHub.