CoplayDev/unity-mcp · error · UnityConnectionError
Failed to list Unity instances
Error message
Failed to list Unity instances
What it means
The terminal fallback raise at the end of list_unity_instances(), reached only when the try block completes without returning and without raising. This happens exclusively when the HTTP GET succeeds (status 200) and response.json() parses, but the resulting dict does NOT contain an 'instances' key — the guard `if 'instances' in data: return data` fails, so the function falls through. It signals a protocol/shape mismatch: the server is up but returned an unexpected response body.
Source
Thrown at Server/src/cli/utils/connection.py:212
except httpx.ConnectError as e:
raise UnityConnectionError(
f"Cannot connect to Unity MCP server at {cfg.host}:{cfg.port}. "
f"Make sure the server is running and Unity is connected.\n"
f"Error: {e}"
)
except httpx.TimeoutException:
raise UnityConnectionError(
"Connection to Unity timed out while listing instances. "
"Unity may be busy or unresponsive."
)
except httpx.HTTPStatusError as e:
raise UnityConnectionError(
f"HTTP error from server: {e.response.status_code} - {e.response.text}"
)
except Exception as e:
raise UnityConnectionError(f"Unexpected error: {e}")
raise UnityConnectionError("Failed to list Unity instances")
def run_list_instances(config: Optional[CLIConfig] = None) -> Dict[str, Any]:
"""Synchronous wrapper for list_unity_instances."""
return asyncio.run(list_unity_instances(config))
async def list_custom_tools(config: Optional[CLIConfig] = None) -> Dict[str, Any]:
"""List custom tools registered for the active Unity project."""
cfg = config or get_config()
url = f"http://{cfg.host}:{cfg.port}/api/custom-tools"
params: Dict[str, Any] = {}
if cfg.unity_instance:
params["instance"] = cfg.unity_instance
try:
async with httpx.AsyncClient() as client:
response = await client.get(url, params=params, timeout=cfg.timeout)View on GitHub (pinned to c21bf496bc)
Solutions
- Manually curl http://127.0.0.1:<port>/api/instances and inspect the JSON keys to see what shape the server actually returns.
- Align CLI and server versions — the 'instances' key is part of the contract; a missing key usually means version mismatch.
- If developing the server, ensure the /api/instances handler always returns {"instances": [...]} even when the list is empty.
- If behind a proxy, bypass it temporarily to confirm the raw server response.
Defensive patterns
Strategy: validation
Validate before calling
import httpx
async def validate_instances_response(host: str, port: int) -> dict | None:
async with httpx.AsyncClient() as c:
r = await c.get(f"http://{host}:{port}/api/instances", timeout=10)
r.raise_for_status()
data = r.json()
if "instances" not in data:
print(f"Unexpected response shape. Keys: {list(data.keys())}")
return None
return data Type guard
def is_instances_payload(data: object) -> bool:
return isinstance(data, dict) and "instances" in data and isinstance(data["instances"], list) Try / catch
from cli.utils.connection import UnityConnectionError
try:
data = run_list_instances(config)
except UnityConnectionError as e:
if "Failed to list Unity instances" in str(e):
# Response shape mismatch — check server/CLI version alignment
print("Server response missing 'instances' key. Verify version match.")
else:
raise Prevention
- Align CLI and server versions so the /api/instances response contract matches.
- When developing the server, always return {"instances": [...]} even if empty.
- In tests, assert the response shape before relying on the data.
When it happens
Trigger: The server responds 200 with a top-level wrapper like {"data": {...}} or {"result": [...]} instead of the expected {"instances": [...]}; an older or newer server version changed the response envelope; a middleware or reverse proxy rewrote the response; the endpoint returned an empty object {} due to a server-side serialization bug.
Common situations: Server/CLI version skew where the response contract changed; a load balancer or API gateway stripped or rewrote the JSON; a development build of the server that returns a different shape; the endpoint handler has a bug that returns an empty dict on a partial failure.
Related errors
- Connection to Unity timed out while listing instances. Unity
- Connection to Unity timed out after {cfg.timeout}s. Unity ma
- Cannot connect to Unity MCP server at {cfg.host}:{cfg.port}.
- Connection to Unity timed out after {timeout or cfg.timeout}
- HTTP error from server: {e.response.status_code} - {e.respon
AI-assisted analysis of CoplayDev/unity-mcp@c21bf496bc (2026-08-13).
Data as JSON: /api/errors/44a1bb3a1fa0fb1a.
Report an issue: GitHub.