redis/redis-py · error · RedisClusterException
Invalid args in command
Error message
Invalid args in command: {args} What it means
Raised as a RedisClusterException by determine_slot() when EVAL or EVALSHA is called with too few arguments (len(args) <= 2), meaning the command is missing the required numkeys parameter. The cluster client special-cases EVAL/EVALSHA to extract keys locally (due to a Redis <7.0 server bug), so it needs at least the command name, script body, and numkeys to proceed.
Solutions
- Provide the full EVAL signature: client.eval(script, numkeys, *keys_and_args) with at least numkeys specified.
- For EVALSHA, ensure all three required parts are present: client.evalsha(sha1, numkeys, *keys_and_args).
Example fix
// before
client.eval('return 1')
// after
client.eval('return 1', 0) Defensive patterns
Strategy: validation
Validate before calling
# Validate EVAL/EVALSHA arity before calling
def safe_eval(client, script, numkeys, *keys_and_args):
if numkeys is None:
raise ValueError('numkeys is required for EVAL in cluster mode')
return client.eval(script, numkeys, *keys_and_args) Type guard
def eval_args_valid(args: list) -> bool:
# EVAL/EVALSHA need at least: command, script/sha, numkeys
return len(args) > 2 Try / catch
null
Prevention
- Always provide the numkeys argument when calling eval() or evalsha().
- For zero-key scripts, explicitly pass numkeys=0: client.eval(script, 0).
- Validate your argument list length before calling execute_command with EVAL/EVALSHA.
When it happens
Trigger: Calling client.eval(script) or client.eval(script, ) with fewer than 3 positional args, or client.execute_command('EVAL', script) without the numkeys argument. The guard at cluster.py:1464-1465 fires.
Common situations: Calling eval() with the wrong arity, forgetting the numkeys argument, or passing a pre-built arg list that was truncated.
Related errors
- method eval() is not implemented
- Invalid args in command
- method load_scripts() is not implemented
- method script_load_for_pipeline() is not implemented
- Passing a host requires passing a port, and vice versa
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/7f1e8b72f40bb827.
Report an issue: GitHub.
Appendix: source
Thrown at redis/cluster.py:1465
# The command contains the slot ID
return args[1]
# Get the keys in the command
# CLIENT TRACKING is a special case.
# It doesn't have any keys, it needs to be sent to the provided nodes
# By default it will be sent to all nodes.
if command.upper() == "CLIENT TRACKING":
return None
# EVAL and EVALSHA are common enough that it's wasteful to go to the
# redis server to parse the keys. Besides, there is a bug in redis<7.0
# where `self._get_command_keys()` fails anyway. So, we special case
# EVAL/EVALSHA.
if command.upper() in ("EVAL", "EVALSHA"):
# command syntax: EVAL "script body" num_keys ...
if len(args) <= 2:
raise RedisClusterException(f"Invalid args in command: {args}")
num_actual_keys = int(args[2])
eval_keys = args[3 : 3 + num_actual_keys]
# if there are 0 keys, that means the script can be run on any node
# so we can just return a random slot
if len(eval_keys) == 0:
return random.randrange(0, REDIS_CLUSTER_HASH_SLOTS)
keys = eval_keys
else:
keys = self._get_command_keys(*args)
if keys is None or len(keys) == 0:
# FCALL can call a function with 0 keys, that means the function
# can be run on any node so we can just return a random slot
if command.upper() in ("FCALL", "FCALL_RO"):
return random.randrange(0, REDIS_CLUSTER_HASH_SLOTS)
raise RedisClusterException(
"No way to dispatch this command to Redis Cluster. "
"Missing key.\nYou can execute the command by specifying "
f"target nodes.\nCommand: {args}"View on GitHub (pinned to 6a6b581b48)