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

  1. Use 'replica' instead of 'slave' for client_list (both refer to the same connection class).
  2. Restrict _type to one of: 'normal', 'master', 'replica', 'pubsub'.
  3. 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

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


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