redis/redis-py · error · RedisClusterException

Cannot identify slot number for command

Error message

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

What it means

Raised by TransactionStrategy.execute_command (redis/cluster.py:4690) when a command in a WATCH/immediate-execution path cannot be assigned a slot number. determine_slot() returned None (the command has no key, or its keys could not be parsed) yet the command is not in NO_SLOTS_COMMANDS, so it cannot be placed in a transaction.

Solutions

  1. Run keyless/admin commands outside the transactional pipeline (rc.info() directly).
  2. Register or supply key info for custom commands so determine_slot can resolve a slot.
  3. Ensure the transactional pipeline only contains genuinely keyed, single-slot commands.

Example fix

// before
with rc.pipeline(transaction=True) as pipe:
    pipe.watch('k')
    pipe.execute_command('DBSIZE')
// after
with rc.pipeline(transaction=True) as pipe:
    pipe.watch('k')
    pipe.get('k')
rc.info()  # keyless command outside the transaction
Defensive patterns

Strategy: validation

Validate before calling

NO_SLOTS = {'PING','INFO','DBSIZE','FLUSHALL','FLUSHDB','CONFIG'}
with rc.pipeline(transaction=True) as pipe:
    pipe.watch('k')
    for cmd in cmds:
        if cmd[0].upper() in NO_SLOTS:
            rc.execute_command(*cmd)  # outside transaction
        else:
            pipe.execute_command(*cmd)

Type guard

def is_keyless_command(name) -> bool:
    return name.upper() in {'PING','INFO','DBSIZE','FLUSHALL','FLUSHDB','CONFIG','TIME'}

Try / catch

from redis.exceptions import RedisClusterException
try:
    pipe.execute_command(*cmd)
except RedisClusterException as e:
    if 'Cannot identify slot' in str(e):
        rc.execute_command(*cmd)  # run keyless command outside transaction

Prevention

When it happens

Trigger: Calling a command that has no keys (or whose keys COMMAND GETKEYS cannot resolve) inside a transactional pipeline's WATCH/immediate path, e.g. pipe.execute_command('INFO') or a custom module command without key metadata while watching.

Common situations: Custom/module commands not registered via COMMAND so the library cannot extract keys; zero-key commands mistaken for keyed ones; RESP2/RESP3 differences in COMMAND INFO output.

Related errors


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

Appendix: source

Thrown at redis/cluster.py:4690

        slot_number: Optional[int] = None
        if args[0] not in ClusterPipeline.NO_SLOTS_COMMANDS:
            slot_number = self._resolve_transaction_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 6a6b581b48)