{"record":{"id":"0d7572b06eec4ec1","repo":"redis/redis-py","slug":"invalid-args-in-command-command-args","errorCode":null,"errorMessage":"Invalid args in command: {command, *args}","messagePattern":"Invalid args in command: (.+?)","errorType":"exception","errorClass":"RedisClusterException","httpStatus":null,"severity":"error","filePath":"redis/asyncio/cluster.py","lineNumber":999,"sourceCode":"        return nodes\n\n    async def _determine_slot(self, command: str, *args: Any) -> int:\n        if self.command_flags.get(command) == SLOT_ID:\n            # The command contains the slot ID\n            return int(args[0])\n\n        # Get the keys in the command\n\n        # EVAL and EVALSHA are common enough that it's wasteful to go to the\n        # redis server to parse the keys. Besides, there is a bug in redis<7.0\n        # where `self._get_command_keys()` fails anyway. So, we special case\n        # EVAL/EVALSHA.\n        # - issue: https://github.com/redis/redis/issues/9493\n        # - fix: https://github.com/redis/redis/pull/9733\n        if command.upper() in (\"EVAL\", \"EVALSHA\"):\n            # command syntax: EVAL \"script body\" num_keys ...\n            if len(args) < 2:\n                raise RedisClusterException(\n                    f\"Invalid args in command: {command, *args}\"\n                )\n            keys = args[2 : 2 + int(args[1])]\n            # if there are 0 keys, that means the script can be run on any node\n            # so we can just return a random slot\n            if not keys:\n                return random.randrange(0, REDIS_CLUSTER_HASH_SLOTS)\n        else:\n            keys = await self.commands_parser.get_keys(command, *args)\n            if not keys:\n                # FCALL can call a function with 0 keys, that means the function\n                #  can be run on any node so we can just return a random slot\n                if command.upper() in (\"FCALL\", \"FCALL_RO\"):\n                    return random.randrange(0, REDIS_CLUSTER_HASH_SLOTS)\n                raise RedisClusterException(\n                    \"No way to dispatch this command to Redis Cluster. \"\n                    \"Missing key.\\nYou can execute the command by specifying \"\n                    f\"target nodes.\\nCommand: {args}\"","sourceCodeStart":981,"sourceCodeEnd":1017,"githubUrl":"https://github.com/redis/redis-py/blob/6a6b581b48225afa0b76912d1028c6035baee932/redis/asyncio/cluster.py#L981-L1017","documentation":"Raised in _determine_slot() for EVAL/EVALSHA when the command has fewer than 2 positional args after the command name. The cluster client needs at least the script body (args[0]) and the numkeys count (args[1]) to extract the keys and compute their slot, so it rejects malformed scripting calls early instead of producing a confusing downstream error.","triggerScenarios":"Calling client.eval() or client.evalsha() with no args, only a script, or only script+numkeys without the actual key arguments such that len(args) < 2. Also triggered by manually building the command via execute_command('EVAL', script) without numkeys.","commonSituations":"Mistakenly passing a pre-joined argument string, forgetting the numkeys parameter, or a wrapper function that drops positional arguments when forwarding to eval().","solutions":["Provide at least (script, numkeys) plus numkeys key arguments: client.eval(script, numkeys, *keys_and_args).","If running a parameterless script on the cluster, pass numkeys=0 so the client routes to a random slot.","Double-check wrapper/adapter code that forwards *args to eval() to ensure nothing is being dropped."],"exampleFix":"// before\nawait rc.eval(\"return 1\")\n\n// after\nawait rc.eval(\"return 1\", 0)","handlingStrategy":"validation","validationCode":"async def safe_eval(rc, script, numkeys, *keys_and_args):\n    if len([script, numkeys, *keys_and_args]) < 2:\n        raise ValueError('eval requires at least (script, numkeys)')\n    return await rc.eval(script, numkeys, *keys_and_args)","typeGuard":"null","tryCatchPattern":"from redis.exceptions import RedisClusterException\ntry:\n    await rc.eval(script, *args)\nexcept RedisClusterException as e:\n    if 'Invalid args in command' in str(e):\n        # fix args and retry with explicit numkeys\n        await rc.eval(script, 0)","preventionTips":["Always pass numkeys as the second positional arg to eval/evalsha.","Prefer the high-level client.eval(script, numkeys, *keys) signature over execute_command('EVAL', ...).","Validate *args length in wrapper functions before forwarding."],"tags":["scripting","eval","cluster","routing"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}