redis/redis-py · error · PubSubError
Pattern: '{pattern}' has no handler registered
Error message
Pattern: '{pattern}' has no handler registered What it means
Raised in `PubSub.run_in_thread` when a pattern subscription (`psubscribe`) has a None handler. Same validation as for channels but iterating `self.patterns`. The worker thread dispatches pmessage frames using the pattern-keyed handler map, so a missing handler is treated as a fatal PubSubError before the thread starts.
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 da03cdc7e8)
Solutions
- Subscribe to patterns with a handler: `ps.psubscribe(**{'user.*': on_user_msg})`.
- Confirm the dict key exactly matches the pattern you intend to handle.
- Use a manual listen()/get_message loop if you do not want per-pattern callbacks.
Example fix
# before
ps.psubscribe('user.*')
ps.run_in_thread() # raises
# after
def on_user(msg):
...
ps.psubscribe(**{'user.*': on_user})
ps.run_in_thread() Defensive patterns
Strategy: validation
Validate before calling
if any(h is None for h in ps.patterns.values()):
raise RuntimeError('Register handlers for all patterns before run_in_thread')
ps.run_in_thread() Type guard
def patterns_have_handlers(ps) -> bool:
return all(h is not None for h in ps.patterns.values()) Prevention
- Pass pattern handlers via psubscribe(**{pattern: handler}).
- Ensure pattern keys match exactly what you will receive.
When it happens
Trigger: Calling `ps.psubscribe('user.*')` without a callback and then `ps.run_in_thread()`. Pattern subscriptions must be registered with a callable (`ps.psubscribe(**{'user.*': handler})`) for the threaded dispatcher to route pmessage frames.
Common situations: Switching a pattern-based pubsub consumer from a manual `listen()` loop to `run_in_thread` without supplying pattern callbacks; typo in the dict key passed to psubscribe causing the handler to land under a different pattern.
Related errors
- Channel: '{channel}' has no handler registered
- Shard Channel: '{s_channel}' has no handler registered
- Buffer is closed.
- Connection closed by server.
- pubsub connection not set: did you forget to call subscribe(
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/3b697299e33f68d3.json.
Report an issue: GitHub.