{"record":{"id":"5f8f4e6c76a6c5f4","repo":"redis/redis-py","slug":"method-multi-is-not-supported-outside-of-transac","errorCode":null,"errorMessage":"method multi() is not supported outside of transactional context","messagePattern":"method multi\\(\\) is not supported outside of transactional context","errorType":"exception","errorClass":"RedisClusterException","httpStatus":null,"severity":"error","filePath":"redis/asyncio/cluster.py","lineNumber":3033,"sourceCode":"                    # Note: when the error is raised we'll reset the default node in the\n                    # caller function.\n                    for cmd in default_node[1]:\n                        # Check if it has a command that failed with a relevant\n                        # exception\n                        if type(cmd.result) in RedisCluster.ERRORS_ALLOW_RETRY:\n                            client.replace_default_node()\n                            break\n\n        return [cmd.result for cmd in stack]\n\n    async def reset(self):\n        \"\"\"\n        Reset back to empty pipeline.\n        \"\"\"\n        self._command_queue = []\n\n    def multi(self):\n        raise RedisClusterException(\n            \"method multi() is not supported outside of transactional context\"\n        )\n\n    async def watch(self, *names):\n        raise RedisClusterException(\n            \"method watch() is not supported outside of transactional context\"\n        )\n\n    async def unwatch(self):\n        raise RedisClusterException(\n            \"method unwatch() is not supported outside of transactional context\"\n        )\n\n    async def discard(self):\n        raise RedisClusterException(\n            \"method discard() is not supported outside of transactional context\"\n        )\n","sourceCodeStart":3015,"sourceCodeEnd":3051,"githubUrl":"https://github.com/redis/redis-py/blob/6a6b581b48225afa0b76912d1028c6035baee932/redis/asyncio/cluster.py#L3015-L3051","documentation":"ClusterPipeline.multi() is a hard error in the non-transactional PipelineStrategy: cluster pipelines created without transaction=True cannot enter a MULTI block, so calling multi() is treated as a programmer mistake. The transactional strategy (TransactionStrategy) is what actually drives MULTI/EXEC inside execute().","triggerScenarios":"Calling pipe.multi() on a pipeline obtained from rc.pipeline() or rc.pipeline(transaction=False). The default cluster pipeline is non-transactional and never supports an explicit multi().","commonSituations":"Porting standalone-client code that calls pipe.multi() to mark the start of a transaction; misunderstanding that cluster pipelines handle transactions via the transaction=True flag, not an explicit multi() call.","solutions":["Create the pipeline with transaction=True: rc.pipeline(transaction=True) and let execute() wrap the queued commands in MULTI/EXEC automatically.","Do not call multi() explicitly; queue commands directly on the pipeline.","Remove any legacy pipe.multi() call when migrating to the cluster pipeline."],"exampleFix":"// before\npipe = rc.pipeline()\npipe.multi()  # raises\npipe.set('a', 1)\nawait pipe.execute()\n\n// after\npipe = rc.pipeline(transaction=True)\npipe.set('a', 1)\nawait pipe.execute()  # MULTI/EXEC handled internally","handlingStrategy":"validation","validationCode":"def transactional_pipeline(rc, transaction=True):\n    pipe = rc.pipeline(transaction=transaction)\n    # do NOT call pipe.multi(); execute() handles MULTI/EXEC\n    return pipe","typeGuard":"null","tryCatchPattern":"from redis.exceptions import RedisClusterException\ntry:\n    pipe.multi()\nexcept RedisClusterException as e:\n    if 'multi() is not supported' in str(e):\n        # recreate as transactional; do not call multi() explicitly\n        pipe = rc.pipeline(transaction=True)","preventionTips":["Create cluster pipelines with transaction=True when you want MULTI/EXEC.","Never call multi() explicitly on a cluster pipeline.","Refactor migrated standalone code to drop the explicit multi() call."],"tags":["cluster","pipeline","transaction","multi"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}