redis/redis-py · error · RedisError
Cannot issue nested calls to MULTI
Error message
Cannot issue nested calls to MULTI
What it means
Raised in `Pipeline.multi()` when `self.explicit_transaction` is already True. `multi()` begins a Redis MULTI/EXEC transactional block; Redis itself forbids nested MULTI, and redis-py enforces this client-side by tracking the explicit_transaction flag. A second call to `multi()` before `execute()`/`discard()` is a programming error.
Source
Thrown at redis/client.py:1889
self.explicit_transaction = False
# we can safely return the connection to the pool here since we're
# sure we're no longer WATCHing anything
if self.connection:
self.connection_pool.release(self.connection)
self.connection = None
def close(self) -> None:
"""Close the pipeline"""
self.reset()
def multi(self) -> None:
"""
Start a transactional block of the pipeline after WATCH commands
are issued. End the transactional block with `execute`.
"""
if self.explicit_transaction:
raise RedisError("Cannot issue nested calls to MULTI")
if self.command_stack:
raise RedisError(
"Commands without an initial WATCH have already been issued"
)
self.explicit_transaction = True
def execute_command(self, *args, **kwargs):
if (self.watching or args[0] == "WATCH") and not self.explicit_transaction:
return self.immediate_execute_command(*args, **kwargs)
return self.pipeline_execute_command(*args, **kwargs)
def _disconnect_reset_raise_on_watching(
self,
conn: AbstractConnection,
error: Exception,
failure_count: Optional[int] = None,
start_time: Optional[float] = None,
command_name: Optional[str] = None,View on GitHub (pinned to da03cdc7e8)
Solutions
- Call `pipe.multi()` exactly once per transaction; end it with `pipe.execute()` or `pipe.discard()`.
- If retrying, create a fresh pipeline (`client.pipeline()`) rather than reusing the already-MULTI'd one.
- Remove the redundant multi() call — pipeline(transaction=True) already issues MULTI implicitly.
Example fix
# before
pipe = client.pipeline()
pipe.multi()
pipe.multi() # raises: Cannot issue nested calls to MULTI
# after
pipe = client.pipeline()
pipe.multi()
pipe.set('k', 'v')
pipe.execute() Defensive patterns
Strategy: validation
Validate before calling
# Track transaction state in your own wrapper to avoid double-multi
pipe = client.pipeline()
multi_called = False
def begin():
global multi_called
if multi_called:
raise RuntimeError('MULTI already issued')
pipe.multi(); multi_called = True Try / catch
from redis.exceptions import RedisError
try:
pipe.multi()
except RedisError as e:
if 'nested calls to MULTI' in str(e):
# already in a transaction — proceed
pass
else:
raise Prevention
- Call multi() at most once per pipeline.
- Create a fresh pipeline for each transaction.
When it happens
Trigger: Calling `pipe.multi()` twice in succession on the same Pipeline without an intervening `execute()` or `discard()`. Also reachable by manually managing transactions and accidentally invoking multi a second time inside a loop or wrapper.
Common situations: Wrapping pipeline in a helper that calls multi() unconditionally; retrying a transaction without resetting the pipeline; copy-paste duplication of the multi() call.
Related errors
- method multi() is not supported outside of transactional con
- method watch() is not supported outside of transactional con
- method unwatch() is not supported outside of transactional c
- method discard() is not supported outside of transactional c
- At least a command with a key is needed to identify a node
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/4d6731ba93fe97c0.json.
Report an issue: GitHub.