redis/redis-py · error · RedisClusterException

deleting multiple keys is not implemented in pipeline…

Error message

deleting multiple keys is not implemented in pipeline command

What it means

Raised by PipelineStrategy.delete() in redis/cluster.py:4568 when more than one key is passed. DEL of multiple keys in a non-transactional cluster pipeline would require cross-slot routing on a single stacked command, which the pipeline cannot do atomically; the implementation deliberately restricts delete() to a single key.

Solutions

  1. Delete keys one at a time in the pipeline: for k in keys: pipe.delete(k).
  2. Use a transactional pipeline if all keys share a hash tag and you need atomicity.
  3. Use rc.delete(*keys) outside a pipeline for standalone-style multi-key delete (cluster client routes per slot).

Example fix

// before
with rc.pipeline() as pipe:
    pipe.delete('k1', 'k2', 'k3')
    pipe.execute()
// after
with rc.pipeline() as pipe:
    for k in ['k1', 'k2', 'k3']:
        pipe.delete(k)
    pipe.execute()
Defensive patterns

Strategy: validation

Validate before calling

keys = ['k1', 'k2', 'k3']
with rc.pipeline() as pipe:
    for k in keys:
        pipe.delete(k)
    pipe.execute()

Type guard

def is_single_key(names) -> bool:
    return len(names) == 1

Try / catch

from redis.exceptions import RedisClusterException
try:
    pipe.delete(*keys)
except RedisClusterException:
    for k in keys:
        pipe.delete(k)

Prevention

When it happens

Trigger: Calling pipe.delete('k1', 'k2', 'k3') (multiple keys) on a non-transactional ClusterPipeline, especially when keys map to different hash slots.

Common situations: Bulk-delete code written for standalone Redis ported to cluster; passing a list/tuple of keys via pipe.delete(*keys).

Related errors


AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10). Data as JSON: /api/errors/e242320060ab9a5f. Report an issue: GitHub.

Appendix: source

Thrown at redis/cluster.py:4568

    def discard(self):
        raise RedisClusterException(
            "method discard() is not supported outside of transactional context"
        )

    def watch(self, *names):
        raise RedisClusterException(
            "method watch() is not supported outside of transactional context"
        )

    def unwatch(self, *names):
        raise RedisClusterException(
            "method unwatch() is not supported outside of transactional context"
        )

    def delete(self, *names):
        if len(names) != 1:
            raise RedisClusterException(
                "deleting multiple keys is not implemented in pipeline command"
            )

        return self.execute_command("DEL", names[0])

    def unlink(self, *names):
        if len(names) != 1:
            raise RedisClusterException(
                "unlinking multiple keys is not implemented in pipeline command"
            )

        return self.execute_command("UNLINK", names[0])


class TransactionStrategy(AbstractStrategy):
    NO_SLOTS_COMMANDS = {"UNWATCH"}
    IMMEDIATE_EXECUTE_COMMANDS = {"WATCH", "UNWATCH"}
    UNWATCH_COMMANDS = {"DISCARD", "EXEC", "UNWATCH"}

View on GitHub (pinned to 6a6b581b48)