redis/redis-py · error · DataError
XACKDEL ref_policy must be one of: KEEPREF, DELREF, ACKED
Error message
XACKDEL ref_policy must be one of: KEEPREF, DELREF, ACKED
What it means
Raised by xackdel() when ref_policy is not one of KEEPREF, DELREF, or ACKED. The reference policy controls how consumer-group PEL (pending entries list) references are handled when entries are acknowledged-and-deleted, and only those three literal values are valid.
Source
Thrown at redis/commands/core.py:6932
) -> Awaitable[int]: ...
def xackdel(
self,
name: KeyT,
groupname: GroupT,
*ids: StreamIdT,
ref_policy: Literal["KEEPREF", "DELREF", "ACKED"] = "KEEPREF",
) -> int | Awaitable[int]:
"""
Combines the functionality of XACK and XDEL. Acknowledges the specified
message IDs in the given consumer group and simultaneously attempts to
delete the corresponding entries from the stream.
"""
if not ids:
raise DataError("XACKDEL requires at least one message ID")
if ref_policy not in {"KEEPREF", "DELREF", "ACKED"}:
raise DataError("XACKDEL ref_policy must be one of: KEEPREF, DELREF, ACKED")
pieces = [name, groupname, ref_policy, "IDS", len(ids)]
pieces.extend(ids)
return self.execute_command("XACKDEL", *pieces)
@overload
def xadd(
self: SyncClientProtocol,
name: KeyT,
fields: Dict[FieldT, EncodableT],
id: StreamIdT = "*",
maxlen: int | None = None,
approximate: bool = True,
nomkstream: bool = False,
minid: StreamIdT | None = None,
limit: int | None = None,
ref_policy: Literal["KEEPREF", "DELREF", "ACKED"] | None = None,
idmpauto: str | None = None,View on GitHub (pinned to da03cdc7e8)
Solutions
- Use one of 'KEEPREF', 'DELREF', 'ACKED' exactly (uppercase).
- Omit ref_policy to accept the default 'KEEPREF'.
- Validate user/config input against the allowed set before calling.
Example fix
# before
await r.xackdel('s', 'g', '1-0', ref_policy='keepref')
# after
await r.xackdel('s', 'g', '1-0', ref_policy='KEEPREF') Defensive patterns
Strategy: type-guard
Validate before calling
VALID_REF_POLICIES = {'KEEPREF', 'DELREF', 'ACKED'}
def validate_ref_policy(policy: str) -> str:
if policy not in VALID_REF_POLICIES:
raise ValueError(f'ref_policy must be one of {VALID_REF_POLICIES}')
return policy Type guard
def is_valid_ref_policy(p: str) -> bool:
return p in {'KEEPREF', 'DELREF', 'ACKED'} Prevention
- Use uppercase exact values: KEEPREF, DELREF, ACKED.
- Omit ref_policy to accept the KEEPREF default.
- Validate config-supplied policy strings against the allowed set.
When it happens
Trigger: Calling client.xackdel(name, group, id, ref_policy='keepref') (wrong case), ref_policy='NONE', or any string outside the allowed set.
Common situations: Case mismatch; passing None expecting a default (the default is KEEPREF only when omitted); typo in policy name.
Related errors
- XACKDEL requires at least one message ID
- XADD ref_policy must be one of: KEEPREF, DELREF, ACKED
- 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='*'
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/61de02f39a8129ea.json.
Report an issue: GitHub.