CoplayDev/unity-mcp · error · ValueError
Command at index {index} must be an object with 'tool' and '
Error message
Command at index {index} must be an object with 'tool' and 'params' keys What it means
During per-command normalization in batch_execute, each element of the commands list must be a dict (JSON object). The check `not isinstance(command, dict)` rejects lists, strings, numbers, None, or any non-mapping type. The error message includes the offending index so the caller can locate the malformed entry. This is a structural contract violation: each command must have 'tool' and 'params' keys.
Source
Thrown at Server/src/services/tools/batch_execute.py:103
"Hint for the maximum number of parallel workers"] = None,
) -> dict[str, Any]:
"""Proxy the batch_execute tool to the Unity Editor transporter."""
unity_instance = await get_unity_instance_from_context(ctx)
if not isinstance(commands, list) or not commands:
raise ValueError(
"'commands' must be a non-empty list of command specifications")
max_commands = await _get_max_commands_from_editor_state(ctx)
if len(commands) > max_commands:
raise ValueError(
f"batch_execute supports up to {max_commands} commands (configured in Unity); received {len(commands)}"
)
normalized_commands: list[dict[str, Any]] = []
for index, command in enumerate(commands):
if not isinstance(command, dict):
raise ValueError(
f"Command at index {index} must be an object with 'tool' and 'params' keys")
tool_name = command.get("tool")
params = command.get("params", {})
if not tool_name or not isinstance(tool_name, str):
raise ValueError(
f"Command at index {index} is missing a valid 'tool' name")
if params is None:
params = {}
if not isinstance(params, dict):
raise ValueError(
f"Command '{tool_name}' must specify parameters as an object/dict")
if "unity_instance" in params:
raise ValueError(
f"Command '{tool_name}' at index {index} contains 'unity_instance'. "View on GitHub (pinned to c21bf496bc)
Solutions
- Wrap each command as an object: {"tool": "<name>", "params": {...}}.
- Check the error message for the index, then fix that specific entry in the commands list.
- Validate the list shape before calling: all(isinstance(c, dict) for c in commands).
Example fix
// before
commands=["manage_gameobject", {"tool": "manage_material", "params": {}}]
// after
commands=[{"tool": "manage_gameobject", "params": {"action": "create"}}, {"tool": "manage_material", "params": {}}] Defensive patterns
Strategy: validation
Validate before calling
# Ensure every command is a dict before calling batch_execute
if not all(isinstance(c, dict) for c in commands):
bad = [i for i, c in enumerate(commands) if not isinstance(c, dict)]
raise ValueError(f"Commands at indices {bad} are not objects") Type guard
def all_commands_are_dicts(commands: list) -> bool:
return isinstance(commands, list) and all(isinstance(c, dict) for c in commands) Prevention
- Build commands as a list of dicts with 'tool' and 'params' keys from the start.
- Never mix bare strings or other types into the commands list.
- Validate list element types before submission.
When it happens
Trigger: A caller passes commands=["manage_gameobject", {...}] mixing a bare string with objects; an LLM emits commands=["create_cube"] treating batch_execute like a variadic string list; a JSON array where one element is a string or number instead of an object; a None element from a sparse array.
Common situations: An AI confuses batch_execute's command shape with a simpler API; a programmatic builder appends a tool name string instead of a {tool, params} dict; JSON deserialization of a mixed-type array; a copy-paste error mixing formats.
Related errors
- 'commands' must be a non-empty list of command specification
- Command at index {index} is missing a valid 'tool' name
- Command '{tool_name}' must specify parameters as an object/d
- batch_execute supports up to {max_commands} commands (config
- Command '{tool_name}' at index {index} contains 'unity_insta
AI-assisted analysis of CoplayDev/unity-mcp@c21bf496bc (2026-08-13).
Data as JSON: /api/errors/b3c02c6842c386e1.
Report an issue: GitHub.