{"id":"61de02f39a8129ea","repo":"redis/redis-py","slug":"xackdel-ref-policy-must-be-one-of-keepref-delref","errorCode":null,"errorMessage":"XACKDEL ref_policy must be one of: KEEPREF, DELREF, ACKED","messagePattern":"XACKDEL ref_policy must be one of: KEEPREF, DELREF, ACKED","errorType":"validation","errorClass":"DataError","httpStatus":null,"severity":"error","filePath":"redis/commands/core.py","lineNumber":6932,"sourceCode":"    ) -> Awaitable[int]: ...\n\n    def xackdel(\n        self,\n        name: KeyT,\n        groupname: GroupT,\n        *ids: StreamIdT,\n        ref_policy: Literal[\"KEEPREF\", \"DELREF\", \"ACKED\"] = \"KEEPREF\",\n    ) -> int | Awaitable[int]:\n        \"\"\"\n        Combines the functionality of XACK and XDEL. Acknowledges the specified\n        message IDs in the given consumer group and simultaneously attempts to\n        delete the corresponding entries from the stream.\n        \"\"\"\n        if not ids:\n            raise DataError(\"XACKDEL requires at least one message ID\")\n\n        if ref_policy not in {\"KEEPREF\", \"DELREF\", \"ACKED\"}:\n            raise DataError(\"XACKDEL ref_policy must be one of: KEEPREF, DELREF, ACKED\")\n\n        pieces = [name, groupname, ref_policy, \"IDS\", len(ids)]\n        pieces.extend(ids)\n        return self.execute_command(\"XACKDEL\", *pieces)\n\n    @overload\n    def xadd(\n        self: SyncClientProtocol,\n        name: KeyT,\n        fields: Dict[FieldT, EncodableT],\n        id: StreamIdT = \"*\",\n        maxlen: int | None = None,\n        approximate: bool = True,\n        nomkstream: bool = False,\n        minid: StreamIdT | None = None,\n        limit: int | None = None,\n        ref_policy: Literal[\"KEEPREF\", \"DELREF\", \"ACKED\"] | None = None,\n        idmpauto: str | None = None,","sourceCodeStart":6914,"sourceCodeEnd":6950,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/commands/core.py#L6914-L6950","documentation":"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.","triggerScenarios":"Calling client.xackdel(name, group, id, ref_policy='keepref') (wrong case), ref_policy='NONE', or any string outside the allowed set.","commonSituations":"Case mismatch; passing None expecting a default (the default is KEEPREF only when omitted); typo in policy name.","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."],"exampleFix":"# before\nawait r.xackdel('s', 'g', '1-0', ref_policy='keepref')\n# after\nawait r.xackdel('s', 'g', '1-0', ref_policy='KEEPREF')","handlingStrategy":"type-guard","validationCode":"VALID_REF_POLICIES = {'KEEPREF', 'DELREF', 'ACKED'}\ndef validate_ref_policy(policy: str) -> str:\n    if policy not in VALID_REF_POLICIES:\n        raise ValueError(f'ref_policy must be one of {VALID_REF_POLICIES}')\n    return policy","typeGuard":"def is_valid_ref_policy(p: str) -> bool:\n    return p in {'KEEPREF', 'DELREF', 'ACKED'}","tryCatchPattern":null,"preventionTips":["Use uppercase exact values: KEEPREF, DELREF, ACKED.","Omit ref_policy to accept the KEEPREF default.","Validate config-supplied policy strings against the allowed set."],"tags":["stream","xackdel","ref-policy","validation","dataerror"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}