redis/redis-py · error · PubSubError

Channel: ' ' has no handler registered

Error message

Channel: '{channel}' has no handler registered

What it means

Raised by PubSub.run_in_thread() when a subscribed channel has no message handler callback registered. run_in_thread dispatches incoming messages to per-channel handlers; if any channel was subscribed without a handler, the worker thread cannot route messages, so the library refuses to start it.

Solutions

  1. Register a handler per channel: pubsub.subscribe(**{'channel': handler_fn}) or pubsub.subscribe(handler_fn, 'channel').
  2. If you intend to poll manually with get_message(), do not call run_in_thread() — use a plain loop instead.
  3. Ensure every channel in pubsub.channels has a non-None handler before calling run_in_thread().

Example fix

// before
pubsub.subscribe('alerts')
pubsub.run_in_thread()  # PubSubError

// after
def on_alert(msg): ...
pubsub.subscribe(**{'alerts': on_alert})
pubsub.run_in_thread()
Defensive patterns

Strategy: validation

Validate before calling

# Ensure every subscribed channel has a handler before starting the worker.
missing = [ch for ch, h in pubsub.channels.items() if h is None]
if missing:
    raise ValueError(f'Channels missing handlers: {missing}')
pubsub.run_in_thread()

Type guard

def all_channels_have_handlers(pubsub) -> bool:
    return all(h is not None for h in pubsub.channels.values())

Try / catch

from redis.exceptions import PubSubError
try:
    pubsub.run_in_thread()
except PubSubError:
    # register handlers then retry
    for ch in list(pubsub.channels):
        pubsub.channels[ch] = default_handler

Prevention

When it happens

Trigger: Calling pubsub.subscribe(channel) (positional, no callback) followed by pubsub.run_in_thread(). The channels dict maps the channel to None, and the validation loop at client.py:1725 raises.

Common situations: Mixing the two subscribe styles: subscribe(name) for manual get_message() polling vs. subscribe(name=handler) for run_in_thread dispatch; refactoring from polling to threaded mode without adding handlers.

Related errors


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

Appendix: source

Thrown at redis/client.py:1727

        elif message_type != "pong":
            # this is a subscribe/unsubscribe message. ignore if we don't
            # want them
            if ignore_subscribe_messages or self.ignore_subscribe_messages:
                return None

        return message

    def run_in_thread(
        self,
        sleep_time: float = 0.0,
        daemon: bool = False,
        exception_handler: Optional[Callable] = None,
        pubsub=None,
        sharded_pubsub: bool = False,
    ) -> "PubSubWorkerThread":
        for channel, handler in self.channels.items():
            if handler is None:
                raise PubSubError(f"Channel: '{channel}' has no handler registered")
        for pattern, handler in self.patterns.items():
            if handler is None:
                raise PubSubError(f"Pattern: '{pattern}' has no handler registered")
        for s_channel, handler in self.shard_channels.items():
            if handler is None:
                raise PubSubError(
                    f"Shard Channel: '{s_channel}' has no handler registered"
                )

        pubsub = self if pubsub is None else pubsub
        thread = PubSubWorkerThread(
            pubsub,
            sleep_time,
            daemon=daemon,
            exception_handler=exception_handler,
            sharded_pubsub=sharded_pubsub,
        )
        thread.start()

View on GitHub (pinned to 6a6b581b48)