{"record":{"id":"5ba1719a36c9eb88","repo":"redis/redis-py","slug":"xdelex-ref-policy-must-be-one-of-keepref-delref","errorCode":null,"errorMessage":"XDELEX ref_policy must be one of: KEEPREF, DELREF, ACKED","messagePattern":"XDELEX ref_policy must be one of: KEEPREF, DELREF, ACKED","errorType":"validation","errorClass":"DataError","httpStatus":null,"severity":"error","filePath":"redis/commands/core.py","lineNumber":7378,"sourceCode":"        *ids: StreamIdT,\n        ref_policy: Literal[\"KEEPREF\", \"DELREF\", \"ACKED\"] = \"KEEPREF\",\n    ) -> Awaitable[int]: ...\n\n    def xdelex(\n        self,\n        name: KeyT,\n        *ids: StreamIdT,\n        ref_policy: Literal[\"KEEPREF\", \"DELREF\", \"ACKED\"] = \"KEEPREF\",\n    ) -> int | Awaitable[int]:\n        \"\"\"\n        Extended version of XDEL that provides more control over how message entries\n        are deleted concerning consumer groups.\n        \"\"\"\n        if not ids:\n            raise DataError(\"XDELEX requires at least one message ID\")\n\n        if ref_policy not in {\"KEEPREF\", \"DELREF\", \"ACKED\"}:\n            raise DataError(\"XDELEX ref_policy must be one of: KEEPREF, DELREF, ACKED\")\n\n        pieces = [name, ref_policy, \"IDS\", len(ids)]\n        pieces.extend(ids)\n        return self.execute_command(\"XDELEX\", *pieces)\n\n    @overload\n    def xgroup_create(\n        self: SyncClientProtocol,\n        name: KeyT,\n        groupname: GroupT,\n        id: StreamIdT = \"$\",\n        mkstream: bool = False,\n        entries_read: int | None = None,\n    ) -> bool: ...\n\n    @overload\n    def xgroup_create(\n        self: AsyncClientProtocol,","sourceCodeStart":7360,"sourceCodeEnd":7396,"githubUrl":"https://github.com/redis/redis-py/blob/6a6b581b48225afa0b76912d1028c6035baee932/redis/commands/core.py#L7360-L7396","documentation":"Raised by Redis.xdelex() when ref_policy is not one of 'KEEPREF', 'DELREF', 'ACKED'. The check is a set membership test; values are case-sensitive and must be uppercase.","triggerScenarios":"Calling r.xdelex('mystream', '1-0', ref_policy='keepref') (lowercase), ref_policy='DELETE', or a typo like 'KEEPRF'.","commonSituations":"Lowercasing the value from config, guessing the enum, or mixing it up with XNACK modes.","solutions":["Use one of the exact uppercase literals: 'KEEPREF', 'DELREF', or 'ACKED'.","Coerce config: ref_policy = str(ref_policy).upper(); validate against the set."],"exampleFix":"# before\nr.xdelex('mystream', '1-0', ref_policy='keepref')\n\n# after\nr.xdelex('mystream', '1-0', ref_policy='KEEPREF')","handlingStrategy":"validation","validationCode":"POLICIES = {'KEEPREF', 'DELREF', 'ACKED'}\nref_policy = str(ref_policy).upper()\nif ref_policy not in POLICIES:\n    raise ValueError('ref_policy must be one of %s' % POLICIES)","typeGuard":"lambda p: p in {'KEEPREF', 'DELREF', 'ACKED'}","tryCatchPattern":"from redis.exceptions import DataError\ntry:\n    r.xdelex('mystream', *ids, ref_policy=rp)\nexcept DataError as e:\n    log.warning('bad xdelex ref_policy %r: %s', rp, e)","preventionTips":["Uppercase and validate enum values at the config boundary; the check is case-sensitive."],"tags":["stream","xdelex","validation","enum"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}