redis/redis-py · error · RuntimeError
pubsub connection not set: did you forget to call…
Error message
pubsub connection not set: did you forget to call subscribe() or psubscribe()?
What it means
Raised by PubSub.parse_response() when self.connection is None — i.e. the PubSub object has never had a connection bound to it. A connection is only created lazily by subscribe()/psubscribe()/ssubscribe(), so calling parse_response() before any subscribe call has no socket to read from.
Solutions
- Call subscribe()/psubscribe()/ssubscribe() with at least one channel/pattern before parse_response() or get_message().
- Verify pubsub.connection is not None before reading, or wrap get_message() in a guard.
- Ensure you are not reusing a PubSub object after calling close()/reset().
Example fix
// before
pubsub = r.pubsub()
msg = pubsub.get_message(timeout=1.0) # RuntimeError
// after
pubsub = r.pubsub()
pubsub.subscribe('channel')
msg = pubsub.get_message(timeout=1.0) Defensive patterns
Strategy: validation
Validate before calling
if pubsub.connection is None:
pubsub.subscribe('channel') # bind a connection first
response = pubsub.parse_response(block=False, timeout=0.1) Type guard
def pubsub_is_subscribed(pubsub) -> bool:
return pubsub.connection is not None Try / catch
if pubsub.connection is None:
raise RuntimeError('Call subscribe() before polling')
msg = pubsub.get_message(timeout=0.1) Prevention
- Always subscribe before get_message()/parse_response().
- Do not reuse a PubSub after close(); obtain a new one via client.pubsub().
- Centralize pubsub lifecycle in a helper that enforces subscribe-first ordering.
When it happens
Trigger: Calling pubsub.parse_response() (directly or via get_message()) on a PubSub object before calling subscribe(), psubscribe(), or ssubscribe(). Also reachable if the connection was explicitly closed/reset before parse_response.
Common situations: Ordering bug: get_message() invoked before subscribe(); copy-pasting example code that omits the subscribe step; calling close() on the pubsub then continuing to poll.
Related errors
- A non health check response was cleaned by execute_command
- Buffer is closed.
- Channel: ' ' has no handler registered
- Pattern: ' ' has no handler registered
- pubsub connection not set: did you forget to call…
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/ef8e08c578caca79.
Report an issue: GitHub.
Appendix: source
Thrown at redis/client.py:1377
block=False when a timeout is provided, and block=True when timeout=None.
Example:
# Block indefinitely (timeout is ignored)
response = pubsub.parse_response(block=True, timeout=0.1)
# Non-blocking with 0.1 second timeout
response = pubsub.parse_response(block=False, timeout=0.1)
# Non-blocking, return immediately
response = pubsub.parse_response(block=False, timeout=0)
# Recommended: use get_message() instead
msg = pubsub.get_message(timeout=0.1) # automatically sets block=False
msg = pubsub.get_message(timeout=None) # automatically sets block=True
"""
conn = self.connection
if conn is None:
raise RuntimeError(
"pubsub connection not set: "
"did you forget to call subscribe() or psubscribe()?"
)
self.check_health()
def try_read():
if not block:
if not conn.can_read(timeout=timeout):
return None
read_timeout = timeout
else:
conn.connect()
# Block indefinitely waiting for a pubsub message. timeout=None
# makes the socket layer call sock.settimeout(None) for this read
# (and restore the original socket_timeout afterwards), so the
# configured socket_timeout does not abort the read.
read_timeout = NoneView on GitHub (pinned to 6a6b581b48)