{"record":{"id":"402d3db6aefbffb7","repo":"redis/redis-py","slug":"method-multi-is-not-supported-outside-of-transac-402d3d","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/cluster.py","lineNumber":4547,"sourceCode":"\n        policy_callback = self._pipe._policies_callback_mapping[request_policy]\n\n        if request_policy == RequestPolicy.DEFAULT_KEYED:\n            nodes = policy_callback(command, *args)\n        elif request_policy == RequestPolicy.MULTI_SHARD:\n            nodes = policy_callback(*args, **kwargs)\n        elif request_policy == RequestPolicy.DEFAULT_KEYLESS:\n            nodes = policy_callback(args[0])\n        else:\n            nodes = policy_callback()\n\n        if args[0].lower() == \"ft.aggregate\":\n            self._aggregate_nodes = nodes\n\n        return nodes\n\n    def multi(self):\n        raise RedisClusterException(\n            \"method multi() is not supported outside of transactional context\"\n        )\n\n    def discard(self):\n        raise RedisClusterException(\n            \"method discard() is not supported outside of transactional context\"\n        )\n\n    def watch(self, *names):\n        raise RedisClusterException(\n            \"method watch() is not supported outside of transactional context\"\n        )\n\n    def unwatch(self, *names):\n        raise RedisClusterException(\n            \"method unwatch() is not supported outside of transactional context\"\n        )\n","sourceCodeStart":4529,"sourceCodeEnd":4565,"githubUrl":"https://github.com/redis/redis-py/blob/6a6b581b48225afa0b76912d1028c6035baee932/redis/cluster.py#L4529-L4565","documentation":"Raised by AbstractStrategy.multi() in redis/cluster.py:4547. In Redis Cluster a MULTI/EXEC transaction must run on a single connection pinned to one slot, so multi() is only valid when invoked through the cluster transaction pipeline entry point. Calling multi() directly on a plain (non-transactional) cluster pipeline has no meaning and is rejected.","triggerScenarios":"Calling pipe.multi() on a ClusterPipeline that was not opened as a transaction: rc.pipeline(transaction=False) or the default non-transactional pipeline, then invoking .multi() to start a transaction mid-stream.","commonSituations":"Copy-paste from standalone redis.Redis pipeline code where .multi() is used explicitly; attempting to start a transaction lazily after queuing non-transactional commands.","solutions":["Open the pipeline as a transaction from the start: with rc.pipeline(transaction=True) as pipe: ...","Remove the explicit .multi() call; the transactional pipeline handles MULTI implicitly on execute().","Use the default non-transactional pipeline and drop the multi() call entirely if atomicity is not needed."],"exampleFix":"// before\nwith rc.pipeline() as pipe:\n    pipe.multi()\n    pipe.set('k', 'v')\n    pipe.execute()\n// after\nwith rc.pipeline(transaction=True) as pipe:\n    pipe.set('k', 'v')\n    pipe.execute()","handlingStrategy":"validation","validationCode":"with rc.pipeline(transaction=True) as pipe:\n    pipe.set('k', 'v')\n    pipe.execute()  # MULTI handled implicitly; no .multi() call","typeGuard":"def is_transactional_pipe(pipe) -> bool:\n    return getattr(pipe, '_transaction_strategy', None) is not None or pipe.transaction","tryCatchPattern":"from redis.exceptions import RedisClusterException\ntry:\n    pipe.multi()\nexcept RedisClusterException:\n    # reopen as transactional\n    pipe = rc.pipeline(transaction=True)","preventionTips":["Open transactional pipelines with transaction=True up front.","Remove explicit .multi() calls when porting to cluster."],"tags":["cluster","pipeline","transaction","api-misuse"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}