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 by Pipeline.watch() when self.explicit_transaction is True — i.e. WATCH is called after MULTI has already started. Redis protocol forbids this: WATCH must precede MULTI. The guard at client.py:2274 catches the misuse client-side before sending anything.
Solutions
- Call watch() BEFORE multi(): the correct order is WATCH → (read) → MULTI → (queue) → EXEC.
- Or use pipeline(transaction=True) and call watch() before execute() — auto-MULTI is issued internally at execute time, so watch() is always pre-MULTI.
- Reset the pipeline and reorder if you called multi() too early.
Example fix
// before
pipe = r.pipeline()
pipe.multi()
pipe.watch('k') # RedisError: Cannot issue a WATCH after a MULTI
// after
pipe = r.pipeline()
pipe.watch('k')
v = pipe.get('k')
pipe.multi()
pipe.set('k', transform(v))
pipe.execute() Defensive patterns
Strategy: validation
Validate before calling
if pipe.explicit_transaction:
raise RuntimeError('Cannot WATCH after MULTI; call watch() before multi()')
pipe.watch('k') Type guard
def pipeline_can_watch(pipe) -> bool:
return not pipe.explicit_transaction 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.reset()
pipe.watch('k') # retry in correct order
else:
raise Prevention
- Order: WATCH before MULTI, always.
- Use pipeline(transaction=True) and call watch() before execute() so MULTI is auto-issued after WATCH.
- Reset the pipeline if you accidentally called multi() first.
When it happens
Trigger: Calling pipe.multi() then pipe.watch(...). The explicit_transaction flag is already True, so watch() raises immediately.
Common situations: Reordering transaction construction (calling multi before watch); helper functions that call watch unconditionally; refactoring code that previously used pipeline(transaction=True) auto-mode.
Related errors
- A occurred while watching one or more keys
- A occurred while watching one or more keys
- Cannot identify slot number for command
- Cannot issue a WATCH after a MULTI
- Cannot issue a WATCH after a MULTI
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/6fc0887133e17e86.
Report an issue: GitHub.
Appendix: 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 6a6b581b48)