redis/redis-py · error · PubSubError

Shard Channel: ' ' has no handler registered

Error message

Shard Channel: '{s_channel}' has no handler registered

What it means

Raised by PubSub.run_in_thread() when a shard channel (SSUBSCRIBE, Redis 7.0 sharded pubsub) has no handler. Same validation as 183/184 but iterating self.shard_channels. Required when sharded_pubsub=True is used with the worker thread.

Solutions

  1. Register a handler per shard channel: pubsub.ssubscribe(**{'shardch': handler_fn}).
  2. Pass sharded_pubsub=True to run_in_thread() and ensure all shard channels have callbacks.
  3. Fall back to manual get_message() polling if handlers are not desired.

Example fix

// before
pubsub.ssubscribe('shardch')
pubsub.run_in_thread(sharded_pubsub=True)  # PubSubError

// after
def on_shard(msg): ...
pubsub.ssubscribe(**{'shardch': on_shard})
pubsub.run_in_thread(sharded_pubsub=True)
Defensive patterns

Strategy: validation

Validate before calling

missing = [c for c, h in pubsub.shard_channels.items() if h is None]
if missing:
    raise ValueError(f'Shard channels missing handlers: {missing}')
pubsub.run_in_thread(sharded_pubsub=True)

Type guard

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

Try / catch

from redis.exceptions import PubSubError
try:
    pubsub.run_in_thread(sharded_pubsub=True)
except PubSubError:
    for c in list(pubsub.shard_channels):
        pubsub.shard_channels[c] = default_handler

Prevention

When it happens

Trigger: Calling ssubscribe on a PubSub (sharded) without a handler, then run_in_thread(sharded_pubsub=True). The loop at client.py:1731 raises for the None-mapped shard channel.

Common situations: Adopting Redis 7.0 sharded pubsub and reusing non-sharded polling code; forgetting the handler convention for shard channels.

Related errors


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

Appendix: source

Thrown at redis/client.py:1733

        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


class PubSubWorkerThread(threading.Thread):
    def __init__(
        self,

View on GitHub (pinned to 6a6b581b48)