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
- Keep the WATCH/transaction path limited to standard keyed commands whose slot can be derived.
- Move the non-keyed command out of the transaction and run it on the client with target_nodes.
- 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
- Keep WATCH/transaction bodies to standard keyed commands only.
- Run admin/keyless commands on the client with target_nodes, outside the transaction.
- Make sure module/custom commands expose their key spec via COMMAND INFO.
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
- Cannot watch or send commands on different slots
- At least a command with a key is needed to identify a node
- Cannot watch or send commands on different slots
- Cannot identify slot number for command: {args[0]},it cannot
- Cannot issue a WATCH after a MULTI
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/db7de79005f0e548.json.
Report an issue: GitHub.