redis/redis-py · error · DataError
XDELEX ref_policy must be one of: KEEPREF, DELREF, ACKED
Error message
XDELEX ref_policy must be one of: KEEPREF, DELREF, ACKED
What it means
Raised by xdelex() when ref_policy is not one of KEEPREF, DELREF, ACKED. Case-SENSITIVE membership test at core.py:7377. Default is KEEPREF.
Source
Thrown at redis/commands/core.py:7378
*ids: StreamIdT,
ref_policy: Literal["KEEPREF", "DELREF", "ACKED"] = "KEEPREF",
) -> Awaitable[int]: ...
def xdelex(
self,
name: KeyT,
*ids: StreamIdT,
ref_policy: Literal["KEEPREF", "DELREF", "ACKED"] = "KEEPREF",
) -> int | Awaitable[int]:
"""
Extended version of XDEL that provides more control over how message entries
are deleted concerning consumer groups.
"""
if not ids:
raise DataError("XDELEX requires at least one message ID")
if ref_policy not in {"KEEPREF", "DELREF", "ACKED"}:
raise DataError("XDELEX ref_policy must be one of: KEEPREF, DELREF, ACKED")
pieces = [name, ref_policy, "IDS", len(ids)]
pieces.extend(ids)
return self.execute_command("XDELEX", *pieces)
@overload
def xgroup_create(
self: SyncClientProtocol,
name: KeyT,
groupname: GroupT,
id: StreamIdT = "$",
mkstream: bool = False,
entries_read: int | None = None,
) -> bool: ...
@overload
def xgroup_create(
self: AsyncClientProtocol,View on GitHub (pinned to da03cdc7e8)
Solutions
- Use the exact uppercase token: 'KEEPREF', 'DELREF', or 'ACKED'.
- Map config strings: policy = {'keep':'KEEPREF','del':'DELREF','acked':'ACKED'}[cfg].upper().
- Omit ref_policy entirely to get the KEEPREF default; do not pass None.
Example fix
# before
r.xdelex('s', *ids, ref_policy='keepref')
# after
r.xdelex('s', *ids, ref_policy='KEEPREF') Defensive patterns
Strategy: validation
Validate before calling
VALID = {'KEEPREF','DELREF','ACKED'}
policy = str(raw).upper()
if policy not in VALID:
raise ValueError(f'ref_policy must be one of {VALID}')
r.xdelex(name, *ids, ref_policy=policy) Type guard
def is_valid_ref_policy(v) -> bool:
return v in {'KEEPREF','DELREF','ACKED'} Try / catch
from redis.exceptions import DataError
try:
r.xdelex(name, *ids, ref_policy=p)
except DataError:
r.xdelex(name, *ids, ref_policy='KEEPREF') Prevention
- Policy tokens are case-sensitive uppercase.
- Omit the kwarg for the default rather than passing None.
When it happens
Trigger: xdelex(..., ref_policy='delete'), ='keepref' (lowercase), ='NONE', =None. Only the exact uppercase tokens pass.
Common situations: Lowercasing policy names from config; using a different vocabulary (DELETE/REMOVE); passing None expecting the default (the default only applies when the kwarg is omitted, not when explicitly None - None fails the set test).
Related errors
- XDELEX requires at least one message ID
- XNACK mode must be one of: SILENT, FAIL, FATAL
- XCFGSET requires at least one of idmp_duration or idmp_maxsi
- XCFGSET idmp_duration must be an integer between 1 and 300
- XCFGSET idmp_maxsize must be an integer between 1 and 1,000,
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/5ba1719a36c9eb88.json.
Report an issue: GitHub.