{"id":"e242320060ab9a5f","repo":"redis/redis-py","slug":"deleting-multiple-keys-is-not-implemented-in-pipel","errorCode":null,"errorMessage":"deleting multiple keys is not implemented in pipeline command","messagePattern":"deleting multiple keys is not implemented in pipeline command","errorType":"exception","errorClass":"RedisClusterException","httpStatus":null,"severity":"error","filePath":"redis/cluster.py","lineNumber":4546,"sourceCode":"\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\n    def delete(self, *names):\n        if len(names) != 1:\n            raise RedisClusterException(\n                \"deleting multiple keys is not implemented in pipeline command\"\n            )\n\n        return self.execute_command(\"DEL\", names[0])\n\n    def unlink(self, *names):\n        if len(names) != 1:\n            raise RedisClusterException(\n                \"unlinking multiple keys is not implemented in pipeline command\"\n            )\n\n        return self.execute_command(\"UNLINK\", names[0])\n\n\nclass TransactionStrategy(AbstractStrategy):\n    NO_SLOTS_COMMANDS = {\"UNWATCH\"}\n    IMMEDIATE_EXECUTE_COMMANDS = {\"WATCH\", \"UNWATCH\"}\n    UNWATCH_COMMANDS = {\"DISCARD\", \"EXEC\", \"UNWATCH\"}","sourceCodeStart":4528,"sourceCodeEnd":4564,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/cluster.py#L4528-L4564","documentation":"PipelineStrategy.delete() (redis/cluster.py:4544) raises RedisClusterException when len(names) != 1. In a cluster pipeline, DEL is constrained to a single key per call because multi-key DEL would require all keys to share a hash slot and the pipeline does not group them. Call delete() once per key instead.","triggerScenarios":"Calling pipe.delete('k1','k2') (two or more keys, or zero keys) on a cluster pipeline. The length check at redis/cluster.py:4545 fails for any count other than 1.","commonSituations":"Reusing standalone pipeline code that batches a multi-key DEL. Cleanup routines that delete a list of keys in one call. Migration from non-cluster redis where pipe.delete(*keys) is allowed.","solutions":["Delete each key in its own pipeline entry: for k in keys: pipe.delete(k).","If all keys can be hashed to one slot via a hash tag (e.g. {tag}k1, {tag}k2), still delete them one per call through the pipeline.","For bulk deletion without a pipeline, use rc.delete(*keys) only if keys share a slot; otherwise loop."],"exampleFix":"# before\npipe = rc.pipeline()\npipe.delete('k1', 'k2')  # raises: deleting multiple keys\npipe.execute()\n\n# after\npipe = rc.pipeline()\nfor k in ['k1', 'k2']:\n    pipe.delete(k)\npipe.execute()","handlingStrategy":"validation","validationCode":"def pipeline_delete(pipe, keys):\n    # cluster pipeline requires one delete() per key\n    for k in keys:\n        pipe.delete(k)\n    return pipe","typeGuard":null,"tryCatchPattern":"from redis.exceptions import RedisClusterException\n\ntry:\n    pipe.delete(*keys)\nexcept RedisClusterException as e:\n    if 'multiple keys' in str(e):\n        for k in keys:\n            pipe.delete(k)\n    else:\n        raise","preventionTips":["Never pass multiple keys to pipe.delete() in cluster mode; loop instead.","Wrap deletion in a helper that iterates keys one per call.","Remember the cluster pipeline DEL constraint when porting standalone code."],"tags":["cluster","pipeline","keys","del"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}