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
- Pass a handler with each pattern: pubsub.psubscribe(**{'events.*': handler_fn}).
- Use manual get_message() polling in your own loop if you do not want per-pattern callbacks.
- 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
- Use psubscribe(**{pattern: handler}) when going threaded.
- Keep the polling API and the threaded-dispatch API separate in your code.
- Validate pubsub.patterns before run_in_thread().
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
- Channel: ' ' has no handler registered
- Shard Channel: ' ' has no handler registered
- pubsub connection not set: did you forget to call…
- A ``db`` querystring option can only be 0 in cluster mode
- A non health check response was cleaned by execute_command
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)