redis/redis-py · error · PubSubError
Channel: ' ' has no handler registered
Error message
Channel: '{channel}' has no handler registered What it means
Raised at the start of PubSubWorker.run() when iterating self.channels: a channel is present in the subscription map but its handler callback is None. The run loop dispatches messages through registered handlers, so a subscribed channel with no handler is an unrecoverable programming error.
Solutions
- Subscribe with a real callback: await pubsub.subscribe(**{'my-channel': my_handler}).
- If you intend to poll messages yourself (no handlers), use get_message in a loop instead of run().
- Before run(), assert none of pubsub.channels.values() is None.
Example fix
// before
await pubsub.subscribe('my-channel')
await pubsub.run()
// after
async def handler(msg): ...
await pubsub.subscribe(**{'my-channel': handler})
await pubsub.run() Defensive patterns
Strategy: validation
Validate before calling
missing = [ch for ch, h in pubsub.channels.items() if h is None]
assert not missing, f'channels without handlers: {missing}'
await pubsub.run() Type guard
def all_channels_have_handlers(pubsub) -> bool:
return all(h is not None for h in pubsub.channels.values()) Try / catch
try:
await pubsub.run()
except PubSubError as e:
if 'no handler registered' in str(e):
# re-subscribe with handlers, then run again
... Prevention
- When using run(), always subscribe via the kwargs form: subscribe(**{ch: cb}).
- Keep handlers in a dict so you can assert coverage before run().
When it happens
Trigger: Calling pubsub.subscribe(**{channel: callback}) where the callback value is None, then awaiting pubsub.run(...); or mixing positional subscribe('ch') (which leaves handler None) with the callback-based run() API.
Common situations: Switching from the manual get_message polling style to the run()-with-handlers style without re-subscribing with handlers; passing a typo'd variable that resolves to None as the handler.
Related errors
- Pattern: ' ' has no handler registered
- Channel ' ' has no handler registered
- Pattern ' ' has no handler registered
- A non health check response was cleaned by execute_command
- Buffer is closed.
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/0f6fd59c6655827c.
Report an issue: GitHub.
Appendix: source
Thrown at redis/asyncio/client.py:1743
poll_timeout: float = 1.0,
pubsub=None,
) -> None:
"""Process pub/sub messages using registered callbacks.
This is the equivalent of :py:meth:`redis.PubSub.run_in_thread` in
redis-py, but it is a coroutine. To launch it as a separate task, use
``asyncio.create_task``:
>>> task = asyncio.create_task(pubsub.run())
To shut it down, use asyncio cancellation:
>>> task.cancel()
>>> await task
"""
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")
await self.connect()
while True:
try:
if pubsub is None:
await self.get_message(
ignore_subscribe_messages=True, timeout=poll_timeout
)
else:
await pubsub.get_message(
ignore_subscribe_messages=True, timeout=poll_timeout
)
except asyncio.CancelledError:
raise
except BaseException as e:View on GitHub (pinned to 6a6b581b48)