CoplayDev/unity-mcp · error · TimeoutError

Timeout receiving Unity response

Error message

Timeout receiving Unity response

What it means

Raised in the framed receive loop (unity_connection.py:206): a socket.timeout while reading the header or payload is caught and re-raised as TimeoutError('Timeout receiving Unity response'). Unlike error 183 (too many heartbeats), this means the socket itself went silent — no bytes at all within the configured timeout.

Source

Thrown at Server/src/transport/legacy/unity_connection.py:206

                    if payload_len == 0:
                        heartbeat_count += 1
                        logger.debug(
                            f"Received heartbeat frame #{heartbeat_count}")
                        if heartbeat_count >= heartbeat_limit or (time.monotonic() - heartbeat_started) > heartbeat_window:
                            raise TimeoutError(
                                "Unity sent heartbeat frames without payload within configured threshold"
                            )
                        continue
                    if payload_len > FRAMED_MAX:
                        raise ValueError(
                            f"Invalid framed length: {payload_len}")
                    payload = self._read_exact(sock, payload_len)
                    logger.debug(
                        f"Received framed response ({len(payload)} bytes)")
                    return payload
            except socket.timeout as exc:
                logger.warning("Socket timeout during framed receive")
                raise TimeoutError("Timeout receiving Unity response") from exc
            except TimeoutError:
                raise
            except Exception as exc:
                logger.error(f"Error during framed receive: {exc}")
                raise

        chunks = []
        # Respect the socket's currently configured timeout
        try:
            while True:
                chunk = sock.recv(buffer_size)
                if not chunk:
                    if not chunks:
                        raise Exception(
                            "Connection closed before receiving data")
                    break
                chunks.append(chunk)

View on GitHub (pinned to c21bf496bc)

Solutions

  1. Raise UNITY_MCP_CONNECTION_TIMEOUT (and/or framed_receive_timeout) if the command legitimately needs longer.
  2. Confirm Unity is responsive (not frozen on a dialog / infinite loop).
  3. Rely on send_command retry to reconnect and re-attempt.

Example fix

// before
# UNITY_MCP_CONNECTION_TIMEOUT unset (300s) but framed recv stalls sooner

// after
export UNITY_MCP_CONNECTION_TIMEOUT=600
Defensive patterns

Strategy: retry

Validate before calling

import os

def framed_recv_timeout_adequate(estimated_seconds: float) -> bool:
    return float(os.environ.get('UNITY_MCP_CONNECTION_TIMEOUT', 300)) >= estimated_seconds

Type guard

def is_framed_recv_timeout(e: BaseException) -> bool:
    return (isinstance(e, TimeoutError)
            and str(e) == 'Timeout receiving Unity response')

Try / catch

try:
    resp = conn.send_command(cmd, params)
except TimeoutError as e:
    if str(e) == 'Timeout receiving Unity response':
        conn.disconnect()  # clear possibly-stale socket
        resp = conn.send_command(cmd, params)  # retry once
    else:
        raise

Prevention

When it happens

Trigger: receive_full_response in framing mode where Unity stops sending entirely (frozen UI, hard deadlock, no heartbeats either), or a single recv exceeding connection_timeout / framed_receive_timeout.

Common situations: Unity editor frozen (spinning beachball / not responding), a network stall, or connection_timeout set too low for a legitimately heavy command.

Understand the failure class

Related errors


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