redis/redis-py · error · NotImplementedError
Method is not supported in transactional context.
Error message
Method is not supported in transactional context.
What it means
Raised as NotImplementedError by ClusterPipeline.mset_nonatomic. The cluster pipeline is itself transactional (MULTI/EXEC on one node), so the non-atomic MSET helper — which fans out across slots as independent writes — has no meaningful implementation in this context.
Source
Thrown at redis/asyncio/cluster.py:3320
for r, cmd in zip(responses, stack):
if isinstance(r, Exception):
self._annotate_exception(r, cmd.position + 1, cmd.args)
await record_operation_duration(
command_name="TRANSACTION",
duration_seconds=time.monotonic() - start_time,
server_address=self._transaction_connection.host,
server_port=self._transaction_connection.port,
db_namespace=str(self._transaction_connection.db),
error=r,
)
raise r
def mset_nonatomic(
self, mapping: Mapping[AnyKeyT, EncodableT]
) -> "ClusterPipeline":
raise NotImplementedError("Method is not supported in transactional context.")
async def execute(
self, raise_on_error: bool = True, allow_redirections: bool = True
) -> List[Any]:
stack = self._command_queue
if not stack and (not self._watching or not self._pipeline_slots):
return []
return await self._execute_transaction_with_retries(stack, raise_on_error)
async def _execute_transaction_with_retries(
self, stack: List["PipelineCommand"], raise_on_error: bool
):
return await self._retry.call_with_retry(
lambda: self._execute_transaction(stack, raise_on_error),
lambda error, failure_count: self._reinitialize_on_error(
error, failure_count
),View on GitHub (pinned to da03cdc7e8)
Solutions
- Call mset_nonatomic on the non-transactional cluster pipeline: client.pipeline(transaction=False) (or the regular client) instead of the transactional one.
- Use plain mset() (with hash tags if needed) inside the transactional pipeline, or split the mapping into per-slot transactions.
- If you need cross-slot non-atomic mset, use the async cluster client directly: await client.mset_nonatomic(mapping).
Example fix
// before pipe = client.pipeline(transaction=True) await pipe.mset_nonatomic(mapping) # raises [85] // after await client.mset_nonatomic(mapping) # use the client, not the txn pipeline
Defensive patterns
Strategy: validation
Validate before calling
if pipe._transaction:
raise ValueError('Use client.mset_nonatomic, not the transactional pipeline') Try / catch
try:
await pipe.mset_nonatomic(mapping)
except NotImplementedError:
await client.mset_nonatomic(mapping) Prevention
- Use the cluster client (not the transactional pipeline) for mset_nonatomic.
- Remember transactional cluster pipelines are single-node MULTI/EXEC.
When it happens
Trigger: Calling await pipe.mset_nonatomic({...}) on a cluster pipeline object (the transactional pipeline returned by client.pipeline()).
Common situations: Reusing mset_nonatomic from the non-transactional ClusterPipeline API on a transactional pipeline, or copy-pasting code that worked on the async cluster client's pipeline() result.
Related errors
- method eval() is not implemented
- method load_scripts() is not implemented
- method script_load_for_pipeline() is not implemented
- At least a command with a key is needed to identify a node
- Cannot watch or send commands on different slots
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/291124f02087d75b.json.
Report an issue: GitHub.