redis/redis-py · error · DataError

CLIENT REPLY must be one of {replies!r}

Error message

CLIENT REPLY must be one of {replies!r}

What it means

Raised by client_reply when the reply argument is not one of 'ON', 'OFF', or 'SKIP'. The check is case-sensitive (exact membership in ['ON','OFF','SKIP']), so lowercase or mixed-case values are rejected.

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 da03cdc7e8)

Solutions

  1. Pass the exact uppercase constant: 'ON', 'OFF', or 'SKIP'.
  2. Normalize with .upper() if the source may be lowercase: client_reply(mode.upper()).
  3. Remember OFF/SKIP require a client with a timeout and you must catch TimeoutError.

Example fix

# before
r.client_reply('off')
# after
r.client_reply('OFF')
Defensive patterns

Strategy: validation

Validate before calling

VALID_REPLIES = {'ON', 'OFF', 'SKIP'}
reply = str(reply).upper()
if reply not in VALID_REPLIES:
    raise ValueError(f'Invalid CLIENT REPLY mode: {reply}')

Type guard

def is_valid_reply_mode(v: str) -> bool:
    return isinstance(v, str) and v.upper() in {'ON', 'OFF', 'SKIP'}

Prevention

When it happens

Trigger: Calling r.client_reply('on'), r.client_reply('off'), or any non-listed string. Passing an int or object whose value isn't exactly 'ON'/'OFF'/'SKIP'.

Common situations: Developer lowercases the constant from a config file. Typing 'skip' lowercase. Passing a boolean instead of the string mode.

Related errors


AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04). Data as JSON: /data/errors/34208ddfeb981576.json. Report an issue: GitHub.