rohitg00/ai-engineering-from-scratch · error · RuntimeError

{peer.name}: bounded legacy probe returned no result

Error message

{peer.name}: bounded legacy probe returned no result

What it means

The legacy initialize probe completed but _send returned something that is not a dict (None, a string, a list, etc.), so there is no JSON-RPC message to decode. The client refuses to guess and aborts the legacy handshake for that peer.

Source

Thrown at phases/13-tools-and-protocols/08-building-an-mcp-client/code/main.py:373

            raise RuntimeError(
                f"{peer.name}: {trigger}; legacy compatibility is not allowlisted"
            )
        request_id = self._new_id()
        initialize = legacy_request(
            request_id,
            "initialize",
            {
                "protocolVersion": self.supported_legacy[0],
                "capabilities": self.client_capabilities.copy(),
                "clientInfo": CLIENT_INFO.copy(),
            },
        )
        try:
            response = self._send(peer, initialize, self.legacy_probe_timeout_ms)
        except (TimeoutError, ConnectionError) as exc:
            raise RuntimeError(f"{peer.name}: bounded legacy probe failed closed") from exc
        if not isinstance(response, dict):
            raise RuntimeError(f"{peer.name}: bounded legacy probe returned no result")
        kind, payload = decode_rpc_response(response, request_id)
        if kind != "result":
            raise RuntimeError(f"{peer.name}: legacy initialize returned an error")
        result = payload
        version = result.get("protocolVersion")
        capabilities = result.get("capabilities")
        server_info = result.get("serverInfo")
        valid_server_info = (
            isinstance(server_info, dict)
            and isinstance(server_info.get("name"), str)
            and bool(server_info["name"])
            and isinstance(server_info.get("version"), str)
            and bool(server_info["version"])
        )
        if version not in self.supported_legacy:
            raise RuntimeError(f"{peer.name}: unsupported legacy protocol revision")
        if not isinstance(capabilities, dict) or not valid_server_info:
            raise RuntimeError(f"{peer.name}: malformed legacy initialize result")

View on GitHub (pinned to 39ea8a1c6d)

Solutions

  1. Inspect what the transport actually returned for the initialize call
  2. Fix the transport to parse frames into dicts before returning
  3. Check the server logs for a crash during initialize
  4. In tests, make the fake transport return a JSON-RPC response dict

Example fix

// before
def fake_send(peer, msg, timeout):
    return json.dumps({"jsonrpc": "2.0", "id": msg["id"], "result": {}})

// after
def fake_send(peer, msg, timeout):
    return {"jsonrpc": "2.0", "id": msg["id"], "result": {}}
Defensive patterns

Strategy: type-guard

Validate before calling

response = transport.peek_response(peer)
if not isinstance(response, dict):
    fix_transport_parse()  # before running connect_all

Type guard

def is_rpc_message(value) -> bool:
    return isinstance(value, dict) and ("result" in value or "error" in value)

Try / catch

try:
    client.connect_all()
except RuntimeError as e:
    if "returned no result" in str(e):
        log_transport_dump(peer)

Prevention

When it happens

Trigger: _probe_legacy gets a response from self._send(peer, initialize, ...) where isinstance(response, dict) is False — e.g. the transport returns None on close or a raw string payload.

Common situations: Buggy transport shim that returns the raw wire text instead of parsed JSON; server closing the connection mid-handshake so the reader yields None; a mock/fake transport in tests returning the wrong shape.

Related errors


AI-assisted analysis of rohitg00/ai-engineering-from-scratch@39ea8a1c6d (2026-08-26). Data as JSON: /api/errors/dd0d1a5cd3464abe. Report an issue: GitHub.