{"record":{"id":"34208ddfeb981576","repo":"redis/redis-py","slug":"client-reply-must-be-one-of-replies-r","errorCode":null,"errorMessage":"CLIENT REPLY must be one of {replies!r}","messagePattern":"CLIENT REPLY must be one of (.+?)","errorType":"exception","errorClass":"DataError","httpStatus":null,"severity":"error","filePath":"redis/commands/core.py","lineNumber":934,"sourceCode":"        \"\"\"\n        Enable and disable redis server replies.\n\n        ``reply`` Must be ON OFF or SKIP,\n        ON - The default most with server replies to commands\n        OFF - Disable server responses to commands\n        SKIP - Skip the response of the immediately following command.\n\n        Note: When setting OFF or SKIP replies, you will need a client object\n        with a timeout specified in seconds, and will need to catch the\n        TimeoutError.\n        The test_client_reply unit test illustrates this, and\n        conftest.py has a client with a timeout.\n\n        See https://redis.io/commands/client-reply\n        \"\"\"\n        replies = [\"ON\", \"OFF\", \"SKIP\"]\n        if reply not in replies:\n            raise DataError(f\"CLIENT REPLY must be one of {replies!r}\")\n        return self.execute_command(\"CLIENT REPLY\", reply, **kwargs)\n\n    @overload\n    def client_id(self: SyncClientProtocol, **kwargs) -> int: ...\n\n    @overload\n    def client_id(self: AsyncClientProtocol, **kwargs) -> Awaitable[int]: ...\n\n    def client_id(self, **kwargs) -> int | Awaitable[int]:\n        \"\"\"\n        Returns the current connection id\n\n        For more information, see https://redis.io/commands/client-id\n        \"\"\"\n        return self.execute_command(\"CLIENT ID\", **kwargs)\n\n    @overload\n    def client_tracking_on(","sourceCodeStart":916,"sourceCodeEnd":952,"githubUrl":"https://github.com/redis/redis-py/blob/6a6b581b48225afa0b76912d1028c6035baee932/redis/commands/core.py#L916-L952","documentation":"Raised by client_reply() (redis/commands/core.py:934) when the reply argument is not exactly one of ['ON','OFF','SKIP']. Unlike most other validators in this file, the check is case-SENSITIVE against the literal list, so 'on'/'off'/'skip' lowercase are rejected. This is a redis.exceptions.DataError raised before the command is sent.","triggerScenarios":"Calling r.client_reply(\"on\"), r.client_reply(\"Off\"), r.client_reply(\"SKIP \"), or any value not in the exact uppercase set.","commonSituations":"Passing lowercase or title-case from a config enum; receiving the value from user input without normalizing case; trailing whitespace from a file/env var.","solutions":["Pass the exact uppercase token: r.client_reply(\"ON\"), r.client_reply(\"OFF\"), or r.client_reply(\"SKIP\")","Normalize untrusted input: r.client_reply(reply.strip().upper())","Use a Literal type guard so invalid values fail at static-analysis time"],"exampleFix":"# before\nr.client_reply(\"on\")\n# after\nr.client_reply(\"ON\")","handlingStrategy":"validation","validationCode":"reply = reply.strip().upper()\nif reply not in {\"ON\", \"OFF\", \"SKIP\"}:\n    raise ValueError(\"reply must be ON, OFF, or SKIP\")\nr.client_reply(reply)","typeGuard":"from typing import Literal, TypeGuard\nReplyMode = Literal[\"ON\", \"OFF\", \"SKIP\"]\ndef is_reply_mode(v: str) -> TypeGuard[ReplyMode]:\n    return v in {\"ON\", \"OFF\", \"SKIP\"}","tryCatchPattern":"from redis.exceptions import DataError\ntry:\n    r.client_reply(reply)\nexcept DataError as e:\n    if \"must be one of\" in str(e):\n        r.client_reply(reply.strip().upper())\n    else:\n        raise","preventionTips":["Use the exact uppercase token; client_reply is case-sensitive.","Normalize external input with .strip().upper() before calling.","Type the parameter as Literal['ON','OFF','SKIP'] so static checkers catch typos."],"tags":["client-management","validation","dataerror","case-sensitivity"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}