{"record":{"id":"ae0aa81b8960aa79","repo":"CoplayDev/unity-mcp","slug":"command-at-index-index-is-missing-a-valid-tool","errorCode":null,"errorMessage":"Command at index {index} is missing a valid 'tool' name","messagePattern":"Command at index (.+?) is missing a valid 'tool' name","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"Server/src/services/tools/batch_execute.py","lineNumber":110,"sourceCode":"            \"'commands' must be a non-empty list of command specifications\")\n\n    max_commands = await _get_max_commands_from_editor_state(ctx)\n    if len(commands) > max_commands:\n        raise ValueError(\n            f\"batch_execute supports up to {max_commands} commands (configured in Unity); received {len(commands)}\"\n        )\n\n    normalized_commands: list[dict[str, Any]] = []\n    for index, command in enumerate(commands):\n        if not isinstance(command, dict):\n            raise ValueError(\n                f\"Command at index {index} must be an object with 'tool' and 'params' keys\")\n\n        tool_name = command.get(\"tool\")\n        params = command.get(\"params\", {})\n\n        if not tool_name or not isinstance(tool_name, str):\n            raise ValueError(\n                f\"Command at index {index} is missing a valid 'tool' name\")\n\n        if params is None:\n            params = {}\n        if not isinstance(params, dict):\n            raise ValueError(\n                f\"Command '{tool_name}' must specify parameters as an object/dict\")\n\n        if \"unity_instance\" in params:\n            raise ValueError(\n                f\"Command '{tool_name}' at index {index} contains 'unity_instance'. \"\n                \"Per-command instance routing is not supported inside batch_execute. \"\n                \"Set unity_instance on the outer batch_execute call to route the entire batch.\"\n            )\n\n        normalized_commands.append({\n            \"tool\": tool_name,\n            \"params\": params,","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/CoplayDev/unity-mcp/blob/c21bf496bca87d54e75bad048563c3adb1782081/Server/src/services/tools/batch_execute.py#L92-L128","documentation":"In batch_execute's per-command loop, after confirming the command is a dict, the 'tool' key must be present and be a non-empty string. The check `not tool_name or not isinstance(tool_name, str)` catches missing key, None, empty string, and non-string types (e.g., a number). The index is included for locating the bad entry. This guards against dispatching a batch sub-command to a non-existent or unnameable tool.","triggerScenarios":"A command dict omits 'tool' entirely: {\"params\": {...}}; 'tool' is set to null or '' ; 'tool' is a number or list; a caller uses a wrong key like 'name' or 'command' instead of 'tool'.","commonSituations":"An LLM uses 'name' or 'command' as the key instead of 'tool'; a caller copies a tool schema fragment that lacks the tool field; a JSON key typo; a dynamically-built command where the tool name variable was None.","solutions":["Ensure every command dict has \"tool\": \"<exact_tool_name>\" with a non-empty string value.","Check the index in the error message to find the offending entry.","Verify the tool name is a registered MCP tool (e.g., 'manage_gameobject', 'manage_script')."],"exampleFix":"// before\ncommands=[{\"name\": \"manage_gameobject\", \"params\": {\"action\": \"create\"}}]\n// after\ncommands=[{\"tool\": \"manage_gameobject\", \"params\": {\"action\": \"create\"}}]","handlingStrategy":"type-guard","validationCode":"# Ensure every command has a valid non-empty string 'tool'\nfor i, c in enumerate(commands):\n    tool = c.get(\"tool\")\n    if not isinstance(tool, str) or not tool.strip():\n        raise ValueError(f\"Command {i} has no valid 'tool' name\")","typeGuard":"def has_valid_tool_names(commands: list) -> bool:\n    return all(\n        isinstance(c.get(\"tool\"), str) and c.get(\"tool\", \"\").strip() != \"\"\n        for c in commands\n        if isinstance(c, dict)\n    )","tryCatchPattern":null,"preventionTips":["Always use the exact key 'tool' (not 'name' or 'command') with a non-empty string value.","Cross-check tool names against the registered MCP tool list before batching.","Validate tool name presence and type in your command builder."],"tags":["validation","batch-execute","input-shape","tool-name","mcp-tool"],"backgroundTag":null,"analyzedSha":"c21bf496bca87d54e75bad048563c3adb1782081","analyzedAt":"2026-08-13T17:36:56.095Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}