CoplayDev/unity-mcp · error · ConnectionError

Cannot reach {url}: {e}

Error message

Cannot reach {url}: {e}

What it means

Raised by _fetch_url_full (unity_docs.py:100) when urllib's urlopen throws a URLError fetching a Unity ScriptReference page. HTTP-level failures (404, 500) are caught separately as HTTPError and returned as a status code, so this error is strictly transport-level: DNS resolution failure, connection refused, no route to host, or the 10s urlopen timeout expiring with no response.

Source

Thrown at Server/src/services/tools/unity_docs.py:100


async def _fetch_url_full(url: str) -> tuple[int, str, str]:
    """Fetch a URL and return (status_code, body_text, final_url).

    Like _fetch_url but also returns the final URL after any redirects.
    """
    loop = asyncio.get_running_loop()

    def _do_fetch() -> tuple[int, str, str]:
        req = Request(url, headers={"User-Agent": "MCPForUnity/1.0"})
        try:
            with urlopen(req, timeout=10) as resp:
                body = resp.read().decode("utf-8", errors="replace")
                return (resp.status, body, resp.url)
        except HTTPError as e:
            return (e.code, "", url)
        except URLError as e:
            raise ConnectionError(f"Cannot reach {url}: {e}") from e

    return await loop.run_in_executor(None, _do_fetch)


# ---------------------------------------------------------------------------
# HTML parser
# ---------------------------------------------------------------------------

class _UnityDocParser(HTMLParser):
    """Extracts structured data from Unity ScriptReference HTML pages."""

    def __init__(self) -> None:
        super().__init__()
        # Tracking state
        self._in_subsection = False
        self._subsection_depth = 0
        self._subsection_title: str | None = None
        self._in_signature = False

View on GitHub (pinned to c21bf496bc)

Solutions

  1. Verify the host can reach docs.unity3d.com (curl -I https://docs.unity3d.com/ScriptReference/index.html) and configure HTTP(S)_PROXY if a proxy is required.
  2. Retry the call once or twice — URLError is often transient (DNS hiccup, momentary reset).
  3. Confirm DNS resolves docs.unity3d.com and that no firewall is dropping port 443.
  4. If running fully offline, disable/skip docs tools rather than letting every lookup throw.

Example fix

// before
status, body = await _fetch_url(url)

// after — tolerate transient reachability failures at the caller
try:
    status, body = await _fetch_url(url)
except ConnectionError as e:
    return {"status": "unavailable", "detail": str(e)}
Defensive patterns

Strategy: retry

Validate before calling

# Pre-flight reachability check before fetching docs
import socket
from urllib.parse import urlparse

def can_reach(url: str, timeout: float = 3.0) -> bool:
    host = urlparse(url).hostname
    try:
        socket.gethostbyname(host)
        with socket.create_connection((host, 443), timeout=timeout):
            return True
    except OSError:
        return False

Type guard

def is_connection_error(e: BaseException) -> bool:
    return isinstance(e, ConnectionError) and 'Cannot reach' in str(e)

Try / catch

from services.tools.unity_docs import _fetch_url

for attempt in range(3):
    try:
        status, body = await _fetch_url(url)
        break
    except ConnectionError as e:
        if attempt == 2:
            return {"status": "unavailable", "detail": str(e)}
        await asyncio.sleep(0.5 * (attempt + 1))

Prevention

When it happens

Trigger: Calling any unity_docs tool (e.g. get_unity_docs / member lookup) that builds a https://docs.unity3d.com/.../ScriptReference URL and calls _fetch_url/_fetch_url_full while the host has no network path to docs.unity3d.com.

Common situations: Sandboxed/offline CI, a corporate proxy or firewall blocking unity3d.com, a transient DNS or connectivity blip, or a wrong/outdated version segment in the URL that still resolves to a host that drops the connection (note: a real 404 is an HTTPError and does NOT trigger this).

Related errors


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