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

RedisClusterException in the immediate/watching path (redis/asyncio/cluster.py:3190) when a command resolves to no slot (slot_number is None) and is not in NO_SLOTS_COMMANDS. In a WATCH/immediate context every command must be routable to a node; commands without keys (or with keys the library cannot extract) cannot be sent transactionally. This guards against ambiguous routing during a watched transaction.

Solutions

  1. Run keyless/admin commands outside the watched pipeline on the client directly
  2. Ensure any command used in the transaction carries at least one key the router can extract
  3. Register custom command key specifications if using module commands

Example fix

// before
await pipe.watch('k1')
pipe.execute_command('CONFIG', 'GET', 'maxmemory')
// after - run admin command outside the transaction
await client.config_get('maxmemory')
Defensive patterns

Strategy: validation

Validate before calling

from redis.cluster import _determine_slot_async_safe_check  # pseudonym
# ensure command has at least one key before issuing inside a watched pipeline
if command_has_no_key(cmd):
    raise ValueError(f'{cmd} has no key; cannot run in watched transaction')

Try / catch

try:
    await pipe.execute_command(*cmd)
except RedisClusterException as e:
    if 'Cannot identify slot number' in str(e):
        await client.execute_command(*cmd)  # run outside transaction

Prevention

When it happens

Trigger: Issuing a keyless command like CONFIG GET, CLIENT INFO, or INFO inside a watched pipeline before MULTI; using a command whose key extraction the cluster router does not understand.

Common situations: Mixing admin/diagnostic commands into a watched transaction; custom or module commands whose first key position is not in the command table.

Related errors


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

Appendix: source

Thrown at redis/asyncio/cluster.py:3190

        slot_number: Optional[int] = None
        if args[0] not in self.NO_SLOTS_COMMANDS:
            slot_number = await 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 super().execute_command(*args, **kwargs)

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

        self._watching = True

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

View on GitHub (pinned to 6a6b581b48)