redis/redis-py · error · PubSubError

Pattern: ' ' has no handler registered

Error message

Pattern: '{pattern}' has no handler registered

What it means

Raised by PubSub.run_in_thread() when a subscribed pattern (PSUBSCRIBE) has no message handler. Symmetric to 183 but for the patterns dict — every pattern registered via psubscribe must carry a callback when run_in_thread is used.

Solutions

  1. Pass a handler with each pattern: pubsub.psubscribe(**{'events.*': handler_fn}).
  2. Use manual get_message() polling in your own loop if you do not want per-pattern callbacks.
  3. Confirm every key in pubsub.patterns has a callable value before run_in_thread().

Example fix

// before
pubsub.psubscribe('events.*')
pubsub.run_in_thread()  # PubSubError

// after
def on_event(msg): ...
pubsub.psubscribe(**{'events.*': on_event})
pubsub.run_in_thread()
Defensive patterns

Strategy: validation

Validate before calling

missing = [p for p, h in pubsub.patterns.items() if h is None]
if missing:
    raise ValueError(f'Patterns missing handlers: {missing}')
pubsub.run_in_thread()

Type guard

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

Try / catch

from redis.exceptions import PubSubError
try:
    pubsub.run_in_thread()
except PubSubError:
    for p in list(pubsub.patterns):
        pubsub.patterns[p] = default_handler

Prevention

When it happens

Trigger: Calling pubsub.psubscribe('events.*') without a handler, then pubsub.run_in_thread(). The validation loop at client.py:1728 finds the pattern mapped to None and raises.

Common situations: Pattern subscriptions used with the threaded worker; forgetting that psubscribe requires the same handler convention as subscribe when threaded.

Related errors


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

Appendix: source

Thrown at redis/client.py:1730

            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()
        return thread

View on GitHub (pinned to 6a6b581b48)