redis/redis-py · error · DataError
XADD fields must be a non-empty dict
Error message
XADD fields must be a non-empty dict
What it means
Raised by xadd() when fields is not a dict or is an empty dict. XADD requires at least one field/value pair per entry (Redis stream entries cannot be empty), so the client validates that fields is a non-empty mapping before iterating fields.items() to build the command.
Source
Thrown at redis/commands/core.py:7055
)
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)
@overload
def xcfgset(
self: SyncClientProtocol,
name: KeyT,
idmp_duration: int | None = None,
idmp_maxsize: int | None = None,
) -> bytes | str: ...
@overload
def xcfgset(
self: AsyncClientProtocol,
name: KeyT,
idmp_duration: int | None = None,
idmp_maxsize: int | None = None,View on GitHub (pinned to da03cdc7e8)
Solutions
- Pass a non-empty dict, e.g. xadd('s', {'field': 'value'}).
- Guard callers to skip XADD when the fields dict is empty.
- Ensure the value is a dict (not a list of tuples or None) before calling.
Example fix
# before
await r.xadd('s', {})
# after
await r.xadd('s', {'field': 'value'}) Defensive patterns
Strategy: type-guard
Validate before calling
def validate_fields(fields):
if not isinstance(fields, dict) or len(fields) == 0:
raise ValueError('fields must be a non-empty dict')
return True Type guard
def is_valid_fields(f) -> bool:
return isinstance(f, dict) and len(f) > 0 Prevention
- Always pass a non-empty dict for fields.
- Skip XADD when the computed fields dict is empty rather than calling it.
- Ensure the value is a dict, not a list of tuples or None.
When it happens
Trigger: Calling client.xadd(name, {}), client.xadd(name, None), or client.xadd(name, [('f','v')]) (list instead of dict).
Common situations: Building the fields dict dynamically and emitting an entry when the dict is empty; passing None from an optional source; passing a list of pairs instead of a dict.
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/ff66b2e2c8463176.json.
Report an issue: GitHub.