CoplayDev/unity-mcp · error · UnityConnectionError

Unexpected error: {e}

Error message

Unexpected error: {e}

What it means

Thrown by send_command() as a catch-all when an exception is neither ConnectError, TimeoutException, nor HTTPStatusError. It wraps the original exception's message. Because the more specific handlers run first, this indicates an unusual failure such as an invalid URL, a JSON decode error on a non-JSON body, or an SSL/protocol problem.

Source

Thrown at Server/src/cli/utils/connection.py:126

            response.raise_for_status()
            return response.json()
    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(
            f"Connection to Unity timed out after {timeout or cfg.timeout}s. "
            f"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}")


def run_command(
    command_type: str,
    params: Dict[str, Any],
    config: Optional[CLIConfig] = None,
    timeout: Optional[int] = None,
) -> Dict[str, Any]:
    """Synchronous wrapper for send_command.

    Args:
        command_type: The command type
        params: Command parameters
        config: Optional CLI configuration
        timeout: Optional timeout override

    Returns:
        Response dict from Unity

View on GitHub (pinned to c21bf496bc)

Solutions

  1. Read the wrapped exception text to identify the underlying type (e.g. JSONDecodeError, InvalidURL).
  2. If the body is not JSON, check for a proxy or gateway intercepting the request.
  3. Validate UNITY_MCP_HOST is a plain hostname/IP without scheme or path.
  4. Reproduce with verbose httpx logging to capture the original exception.

Example fix

# before
export UNITY_MCP_HOST=http://localhost  # invalid: includes scheme
# after
export UNITY_MCP_HOST=localhost
Defensive patterns

Strategy: try-catch

Validate before calling

import re
host = os.environ.get("UNITY_MCP_HOST", "127.0.0.1")
if not re.fullmatch(r"[A-Za-z0-9.\-]+", host):
    raise ValueError(f"Invalid UNITY_MCP_HOST value: {host!r}")

Try / catch

try:
    return await send_command(cmd, params)
except UnityConnectionError as e:
    # Unexpected: log the wrapped exception for diagnosis
    log.exception(str(e))
    raise

Prevention

When it happens

Trigger: The server returns a non-JSON body causing response.json() to raise; a malformed host value yields an InvalidURL; or an SSL/TLS handshake error occurs against an https endpoint. Any unexpected httpx or stdlib exception falls here.

Common situations: A proxy returns HTML instead of JSON, the host string contains invalid characters, or a TLS mismatch when the endpoint is HTTPS. Often a symptom of misconfigured networking rather than the Unity layer.

Related errors


AI-assisted analysis of CoplayDev/unity-mcp@c21bf496bc (2026-08-13). Data as JSON: /api/errors/435ee7173abcfcf0. Report an issue: GitHub.