redis/redis-py · error · DataError

CLIENT REPLY must be one of

Error message

CLIENT REPLY must be one of {replies!r}

What it means

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.

Solutions

  1. Pass the exact uppercase token: r.client_reply("ON"), r.client_reply("OFF"), or r.client_reply("SKIP")
  2. Normalize untrusted input: r.client_reply(reply.strip().upper())
  3. Use a Literal type guard so invalid values fail at static-analysis time

Example fix

# before
r.client_reply("on")
# after
r.client_reply("ON")
Defensive patterns

Strategy: validation

Validate before calling

reply = reply.strip().upper()
if reply not in {"ON", "OFF", "SKIP"}:
    raise ValueError("reply must be ON, OFF, or SKIP")
r.client_reply(reply)

Type guard

from typing import Literal, TypeGuard
ReplyMode = Literal["ON", "OFF", "SKIP"]
def is_reply_mode(v: str) -> TypeGuard[ReplyMode]:
    return v in {"ON", "OFF", "SKIP"}

Try / catch

from redis.exceptions import DataError
try:
    r.client_reply(reply)
except DataError as e:
    if "must be one of" in str(e):
        r.client_reply(reply.strip().upper())
    else:
        raise

Prevention

When it happens

Trigger: Calling r.client_reply("on"), r.client_reply("Off"), r.client_reply("SKIP "), or any value not in the exact uppercase set.

Common situations: 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.

Related errors


AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10). Data as JSON: /api/errors/34208ddfeb981576. Report an issue: GitHub.

Appendix: source

Thrown at redis/commands/core.py:934

        """
        Enable and disable redis server replies.

        ``reply`` Must be ON OFF or SKIP,
        ON - The default most with server replies to commands
        OFF - Disable server responses to commands
        SKIP - Skip the response of the immediately following command.

        Note: When setting OFF or SKIP replies, you will need a client object
        with a timeout specified in seconds, and will need to catch the
        TimeoutError.
        The test_client_reply unit test illustrates this, and
        conftest.py has a client with a timeout.

        See https://redis.io/commands/client-reply
        """
        replies = ["ON", "OFF", "SKIP"]
        if reply not in replies:
            raise DataError(f"CLIENT REPLY must be one of {replies!r}")
        return self.execute_command("CLIENT REPLY", reply, **kwargs)

    @overload
    def client_id(self: SyncClientProtocol, **kwargs) -> int: ...

    @overload
    def client_id(self: AsyncClientProtocol, **kwargs) -> Awaitable[int]: ...

    def client_id(self, **kwargs) -> int | Awaitable[int]:
        """
        Returns the current connection id

        For more information, see https://redis.io/commands/client-id
        """
        return self.execute_command("CLIENT ID", **kwargs)

    @overload
    def client_tracking_on(

View on GitHub (pinned to 6a6b581b48)