redis/redis-py · error · RedisError
Cannot issue a WATCH after a MULTI
Error message
Cannot issue a WATCH after a MULTI
What it means
Raised in `Pipeline.watch()` when `self.explicit_transaction` is already True. WATCH must precede MULTI; once a MULTI block has started Redis forbids WATCH until after EXEC/DISCARD. redis-py enforces this client-side by checking the explicit_transaction flag and raising RedisError.
Source
Thrown at redis/client.py:2275
)
raise
finally:
# in reset() the connection is disconnected before returned to the pool if
# it is marked for reconnect.
self.reset()
def discard(self):
"""
Flushes all previously queued commands
See: https://redis.io/commands/DISCARD
"""
self.execute_command("DISCARD")
def watch(self, *names):
"""Watches the values at keys ``names``"""
if self.explicit_transaction:
raise RedisError("Cannot issue a WATCH after a MULTI")
return self.execute_command("WATCH", *names)
def unwatch(self) -> bool:
"""Unwatches all previously specified keys"""
return self.watching and self.execute_command("UNWATCH") or True
View on GitHub (pinned to da03cdc7e8)
Solutions
- Issue WATCH before MULTI: `pipe.watch(...); pipe.multi(); ...commands...; pipe.execute()`.
- If you need to watch different keys, start a new pipeline and re-do WATCH->MULTI from scratch.
- Call `pipe.discard()` to abort the current MULTI, then re-establish WATCH in the correct order on a fresh pipeline.
Example fix
# before
pipe = client.pipeline()
pipe.multi()
pipe.watch('k') # raises: Cannot issue a WATCH after a MULTI
# after
pipe = client.pipeline()
pipe.watch('k')
pipe.multi()
pipe.set('k', 'v')
pipe.execute() Defensive patterns
Strategy: validation
Validate before calling
# Enforce correct ordering: WATCH before MULTI
pipe = client.pipeline()
pipe.watch('k') # always before multi()
pipe.multi() Try / catch
from redis.exceptions import RedisError
try:
pipe.watch('k')
except RedisError as e:
if 'Cannot issue a WATCH after a MULTI' in str(e):
pipe = client.pipeline(); pipe.watch('k'); pipe.multi()
else:
raise Prevention
- Sequence WATCH before MULTI, then commands, then EXEC.
- Start a fresh pipeline when changing the watched key set.
When it happens
Trigger: Calling `pipe.multi()` and then `pipe.watch('k')` on the same pipeline. Also reachable by accidentally inverting the order in a helper: multi() then watch() instead of watch() then multi().
Common situations: Misordered transaction setup; refactoring that moved watch() after the multi() call; copy-paste errors.
Related errors
- Cannot issue a WATCH after a MULTI
- method watch() is not supported outside of transactional con
- Commands without an initial WATCH have already been issued
- A {type(error).__name__} occurred while watching one or more
- Watched variable changed.
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/6fc0887133e17e86.json.
Report an issue: GitHub.