redis/redis-py · error · RedisClusterException

Cannot identify slot number for command: {args[0]},it cannot

Error message

Cannot identify slot number for command: {args[0]},it cannot be triggered in a transaction

What it means

Raised in TransactionStrategy.execute_command (redis/cluster.py:4636) when a command sent while watching (or in the immediate-execution path) has no determinable slot number. determine_slot(*args) returned None and the command is not in NO_SLOTS_COMMANDS, so the transaction cannot pin it to a node. This commonly happens for commands with no key or commands whose key position the library cannot introspect.

Source

Thrown at redis/cluster.py:4637

        slot_number: Optional[int] = None
        if args[0] not in ClusterPipeline.NO_SLOTS_COMMANDS:
            slot_number = self._pipe.determine_slot(*args)

        if (
            self._watching or args[0] in self.IMMEDIATE_EXECUTE_COMMANDS
        ) and not self._explicit_transaction:
            if args[0] == "WATCH":
                self._validate_watch()

            if slot_number is not None:
                if self._pipeline_slots and slot_number not in self._pipeline_slots:
                    raise CrossSlotTransactionError(
                        "Cannot watch or send commands on different slots"
                    )

                self._pipeline_slots.add(slot_number)
            elif args[0] not in self.NO_SLOTS_COMMANDS:
                raise RedisClusterException(
                    f"Cannot identify slot number for command: {args[0]},"
                    "it cannot be triggered in a transaction"
                )

            return self._immediate_execute_command(*args, **kwargs)
        else:
            if slot_number is not None:
                self._pipeline_slots.add(slot_number)

            return self.pipeline_execute_command(*args, **kwargs)

    def _validate_watch(self):
        if self._explicit_transaction:
            raise RedisError("Cannot issue a WATCH after a MULTI")

        self._watching = True

    def _immediate_execute_command(self, *args, **options):

View on GitHub (pinned to da03cdc7e8)

Solutions

  1. Keep the WATCH/transaction path limited to standard keyed commands whose slot can be derived.
  2. Move the non-keyed command out of the transaction and run it on the client with target_nodes.
  3. For custom/module commands, ensure COMMAND INFO is available to the cluster client so determine_slot can find the key, or wrap the key in a known slot via hash tag and use the high-level method.

Example fix

# before
pipe = rc.pipeline(transaction=True)
pipe.watch('k')
pipe.execute_command('PING')   # no slot -> raises
pipe.execute()

# after
pipe = rc.pipeline(transaction=True)
pipe.watch('k')
pipe.multi()
pipe.set('k', 'v')
pipe.execute()
rc.ping()  # keyless command outside the transaction
Defensive patterns

Strategy: validation

Validate before calling

KEYLESS = {'PING', 'INFO', 'CONFIG', 'CLIENT', 'FLUSHALL', 'FLUSHDB', 'DBSIZE'}

def safe_txn_command(pipe, cmd, *args):
    if cmd.upper() in KEYLESS:
        raise ValueError(f'{cmd} has no key/slot and cannot run inside a cluster transaction')
    pipe.execute_command(cmd, *args)

Try / catch

from redis.exceptions import RedisClusterException

try:
    pipe.execute_command(cmd, *args)
except RedisClusterException as e:
    if 'Cannot identify slot number' in str(e):
        rc.execute_command(cmd, *args, target_nodes=RedisCluster.PRIMARIES)
    else:
        raise

Prevention

When it happens

Trigger: Issuing a keyless or un-introspectable command while watching: e.g. pipe.watch('k'); pipe.execute_command('PING') or a custom/module command whose key spec COMMAND INFO does not expose. The slot cannot be derived, so the transaction aborts.

Common situations: Mixing admin or custom commands into a WATCH block. Module commands whose COMMAND INFO key position is not loaded. Calling execute_command directly with an unknown verb inside a transaction.

Related errors


AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04). Data as JSON: /data/errors/db7de79005f0e548.json. Report an issue: GitHub.