rohitg00/ai-engineering-from-scratch · error · RuntimeError
{peer.name}: malformed legacy initialize result
Error message
{peer.name}: malformed legacy initialize result What it means
The legacy initialize result passed the version check but its capabilities field is not a dict, or serverInfo is missing/not a dict with non-empty string name and version. The client validates the full legacy result shape before activating the peer and treats a malformed payload as a hard failure.
Source
Thrown at phases/13-tools-and-protocols/08-building-an-mcp-client/code/main.py:391
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")
peer.era = "legacy"
peer.protocol_version = version
peer.capabilities = capabilities
peer.server_info = server_info
peer.available = True
self._send(
peer,
{"jsonrpc": "2.0", "method": "notifications/initialized", "params": {}}
)
def _connect_peer(self, peer: Peer) -> None:
if peer.available and peer.era in {"modern", "legacy"}:
return
request_id = self._new_id()
probe = modern_request(
request_id,
"server/discover",
{},View on GitHub (pinned to 39ea8a1c6d)
Solutions
- Log the raw legacy initialize result and inspect capabilities/serverInfo
- Fix the server to return capabilities as an object and serverInfo with non-empty string name and version
- If the server is third-party, disable legacy for that peer and require modern discovery
Example fix
// before (server)
result = {"protocolVersion": "2024-11-05", "serverInfo": {"name": "srv", "version": 1}}
// after
result = {"protocolVersion": "2024-11-05", "capabilities": {}, "serverInfo": {"name": "srv", "version": "1.0.0"}} Defensive patterns
Strategy: validation
Validate before calling
result = dry_run_legacy_initialize(peer)
ok = (isinstance(result.get('capabilities'), dict)
and isinstance(result.get('serverInfo'), dict)
and isinstance(result['serverInfo'].get('name'), str)
and isinstance(result['serverInfo'].get('version'), str))
if not ok:
fix_server_initialize_result(peer) Type guard
def valid_legacy_result(result) -> bool:
return (isinstance(result, dict)
and isinstance(result.get('capabilities'), dict)
and isinstance(result.get('serverInfo'), dict)
and isinstance(result['serverInfo'].get('name'), str)
and result['serverInfo'].get('name')
and isinstance(result['serverInfo'].get('version'), str)
and result['serverInfo'].get('version')) Try / catch
null
Prevention
- Contract-test the server's initialize result shape
- Never hand-roll initialize responses without all required fields
When it happens
Trigger: version is in supported_legacy but capabilities is not a dict, or serverInfo fails the isinstance/name/version string checks encoded in valid_server_info.
Common situations: Hand-rolled legacy server returning partial initialize results; serverInfo with numeric version or empty name; capabilities serialized as a list or null by a buggy serializer.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- {peer.name}: legacy initialize returned an error
- {peer.name}: unsupported legacy protocol revision
- {peer.name}: {trigger}; legacy compatibility is not allowlis
- {peer.name}: bounded legacy probe failed closed
- {peer.name}: bounded legacy probe returned no result
AI-assisted analysis of rohitg00/ai-engineering-from-scratch@39ea8a1c6d (2026-08-26).
Data as JSON: /api/errors/d4079f75185b4261.
Report an issue: GitHub.