redis/redis-py · error · RedisClusterException
method watch() is not supported outside of transactional…
Error message
method watch() is not supported outside of transactional context
What it means
Raised by AbstractStrategy.watch() in redis/cluster.py:4557. WATCH is a conditional-transaction primitive that must be sent on the connection owning the watched key's slot; on a non-transactional cluster pipeline there is no pinned connection, so watch() is rejected. Only the TransactionStrategy supports WATCH (via _validate_watch / immediate execution).
Solutions
- Use a transactional pipeline: with rc.pipeline(transaction=True) as pipe: pipe.watch('k'); pipe.multi(); ...
- Ensure all watched keys hash to the same slot (use hash tags {tag}key1, {tag}key2).
- If you only need conditional execution without atomicity, reconsider whether WATCH is necessary.
Example fix
// before
pipe = rc.pipeline()
pipe.watch('k')
// after
with rc.pipeline(transaction=True) as pipe:
pipe.watch('k')
val = pipe.get('k').execute()[0]
pipe.multi()
pipe.set('k', newval)
pipe.execute() Defensive patterns
Strategy: validation
Validate before calling
with rc.pipeline(transaction=True) as pipe:
pipe.watch('k') # OK in transactional pipeline Type guard
def is_transactional_pipe(pipe) -> bool:
return bool(getattr(pipe, 'transaction', False)) Try / catch
from redis.exceptions import RedisClusterException
try:
pipe.watch('k')
except RedisClusterException:
with rc.pipeline(transaction=True) as tpipe:
tpipe.watch('k') Prevention
- Always use transaction=True when you need WATCH.
- Use hash tags so all watched keys share a slot.
When it happens
Trigger: Calling pipe.watch('key') on a ClusterPipeline opened without transaction=True, or calling watch() before the transactional context is established.
Common situations: Porting optimistic-locking code (WATCH/MULTI/EXEC) from standalone Redis to cluster; assuming watch works on the default pipeline.
Related errors
- Cannot issue a WATCH after a MULTI
- Cannot watch or send commands on different slots
- method discard() is not supported outside of transactional…
- method multi() is not supported outside of transactional…
- method unwatch() is not supported outside of transactional…
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/a2400dd8b38b0853.
Report an issue: GitHub.
Appendix: source
Thrown at redis/cluster.py:4557
nodes = policy_callback()
if args[0].lower() == "ft.aggregate":
self._aggregate_nodes = nodes
return nodes
def multi(self):
raise RedisClusterException(
"method multi() is not supported outside of transactional context"
)
def discard(self):
raise RedisClusterException(
"method discard() is not supported outside of transactional context"
)
def watch(self, *names):
raise RedisClusterException(
"method watch() is not supported outside of transactional context"
)
def unwatch(self, *names):
raise RedisClusterException(
"method unwatch() is not supported outside of transactional context"
)
def delete(self, *names):
if len(names) != 1:
raise RedisClusterException(
"deleting multiple keys is not implemented in pipeline command"
)
return self.execute_command("DEL", names[0])
def unlink(self, *names):
if len(names) != 1:View on GitHub (pinned to 6a6b581b48)