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
- 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
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
- 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.
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
- client_id must be a list
- CLIENT KILL ... ... must specify at least one filter
- CLIENT KILL skipme must be a bool
- CLIENT LIST _type must be one of
- CLIENT PAUSE timeout must be an integer
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)