{"record":{"id":"ead0dfefabaa8fbb","repo":"redis/redis-py","slug":"method-watch-is-not-supported-outside-of-transac","errorCode":null,"errorMessage":"method watch() is not supported outside of transactional context","messagePattern":"method watch\\(\\) is not supported outside of transactional context","errorType":"exception","errorClass":"RedisClusterException","httpStatus":null,"severity":"error","filePath":"redis/asyncio/cluster.py","lineNumber":3038,"sourceCode":"                        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\n    async def unlink(self, *names):\n        if len(names) != 1:\n            raise RedisClusterException(\n                \"unlinking multiple keys is not implemented in pipeline command\"\n            )","sourceCodeStart":3020,"sourceCodeEnd":3056,"githubUrl":"https://github.com/redis/redis-py/blob/6a6b581b48225afa0b76912d1028c6035baee932/redis/asyncio/cluster.py#L3020-L3056","documentation":"ClusterPipeline.watch() raises unconditionally in the non-transactional PipelineStrategy. WATCH is a transaction primitive that must be issued inside a transactional context against a single node; the default non-transactional cluster pipeline cannot honour it, so the call is rejected.","triggerScenarios":"Calling await pipe.watch('key') on a pipeline created with rc.pipeline() (transaction defaults False). The method exists on the class only to satisfy the abstract strategy interface.","commonSituations":"Migrating optimistic-locking code (WATCH/MULTI/EXEC) from the standalone client to the cluster client without enabling transaction mode; calling watch() on a pipeline you intend to use purely for batching.","solutions":["Use rc.pipeline(transaction=True) which wires up WATCH through the transactional strategy.","For cluster-wide optimistic locking, restrict watched keys to a single slot (shared hash tag) so a one-node WATCH is valid.","If you only need batching without transactions, drop the watch() call entirely."],"exampleFix":"// before\npipe = rc.pipeline()\nawait pipe.watch('account:1')  # raises\n\n// after\npipe = rc.pipeline(transaction=True)\nawait pipe.watch('{acct}:1')\npipe.multi()  # supported inside transactional strategy\npipe.decrby('{acct}:1', 10)\nawait pipe.execute()","handlingStrategy":"validation","validationCode":"async def cluster_watch(rc, key):\n    pipe = rc.pipeline(transaction=True)\n    await pipe.watch(key)  # valid only in transactional pipeline\n    return pipe","typeGuard":"null","tryCatchPattern":"from redis.exceptions import RedisClusterException\ntry:\n    await pipe.watch(key)\nexcept RedisClusterException as e:\n    if 'watch() is not supported' in str(e):\n        pipe = rc.pipeline(transaction=True)\n        await pipe.watch(key)","preventionTips":["Use rc.pipeline(transaction=True) before calling watch().","Keep watched keys under one hash tag so they sit on one node.","Drop watch() from non-transactional batching pipelines."],"tags":["cluster","pipeline","transaction","watch"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}