redis/redis-py · error · DataError
CLIENT LIST _type must be one of {client_types!r}
Error message
CLIENT LIST _type must be one of {client_types!r} What it means
Raised by client_list when the _type argument is not one of ('normal', 'master', 'replica', 'pubsub'). Note this tuple differs from client_kill's: 'slave' is NOT accepted here, only four values. The check is case-insensitive.
Source
Thrown at redis/commands/core.py:856
def client_list(
self, _type: str | None = None, client_id: List[EncodableT] = [], **kwargs
) -> list[dict[str, str]] | Awaitable[list[dict[str, str]]]:
"""
Returns a list of currently connected clients.
If type of client specified, only that type will be returned.
:param _type: optional. one of the client types (normal, master,
replica, pubsub)
:param client_id: optional. a list of client ids
For more information, see https://redis.io/commands/client-list
"""
args = []
if _type is not None:
client_types = ("normal", "master", "replica", "pubsub")
if str(_type).lower() not in client_types:
raise DataError(f"CLIENT LIST _type must be one of {client_types!r}")
args.append(b"TYPE")
args.append(_type)
if not isinstance(client_id, list):
raise DataError("client_id must be a list")
if client_id:
args.append(b"ID")
args += client_id
return self.execute_command("CLIENT LIST", *args, **kwargs)
@overload
def client_getname(self: SyncClientProtocol, **kwargs) -> bytes | str | None: ...
@overload
def client_getname(
self: AsyncClientProtocol, **kwargs
) -> Awaitable[bytes | str | None]: ...
def client_getname(self, **kwargs) -> (bytes | str | None) | Awaitable[View on GitHub (pinned to da03cdc7e8)
Solutions
- Use 'replica' instead of 'slave' for client_list (both refer to the same connection class).
- Restrict _type to one of: 'normal', 'master', 'replica', 'pubsub'.
- Omit _type entirely to list all connected clients regardless of type.
Example fix
# before r.client_list(_type='slave') # after r.client_list(_type='replica')
Defensive patterns
Strategy: validation
Validate before calling
VALID_LIST_TYPES = {'normal', 'master', 'replica', 'pubsub'}
if _type is not None and str(_type).lower() not in VALID_LIST_TYPES:
raise ValueError(f'Invalid client_list type: {_type}') Type guard
def is_valid_list_type(t: str) -> bool:
return isinstance(t, str) and t.lower() in {'normal', 'master', 'replica', 'pubsub'} Prevention
- client_list and client_kill accept DIFFERENT _type vocabularies — 'slave' is kill-only.
- Prefer 'replica' over 'slave' everywhere for forward compatibility.
When it happens
Trigger: Calling r.client_list(_type='slave') — valid for client_kill but rejected here. Passing _type='all', _type='worker', or any non-matching string.
Common situations: Developer uses the same _type vocabulary for both client_kill and client_list, not realizing client_list omits 'slave'. Legacy code migrated from client_kill calls. Using 'slave' for backward-compat with older Redis naming.
Related errors
- CLIENT KILL type must be one of {client_types!r}
- CLIENT KILL skipme must be a bool
- CLIENT KILL <filter> <value> ... ... <filter> <value> must s
- client_id must be a list
- CLIENT REPLY must be one of {replies!r}
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/3c1303db54e9934a.json.
Report an issue: GitHub.