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

{peer.name}: proven-modern discovery retry returned an error

Error message

{peer.name}: proven-modern discovery retry returned an error

What it means

The versioned discovery retry returned a valid JSON-RPC message that decoded as an error rather than a result. Even after agreeing on a version, the server refused the retry, so activation is aborted — the client does not fall back to legacy from this state.

Source

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

            if selected is None:
                raise RuntimeError(f"{peer.name}: no mutually supported modern version")
            retry_id = self._new_id()
            retry = modern_request(
                retry_id,
                "server/discover",
                {},
                selected,
                self.client_capabilities,
            )
            try:
                retried = self._send(peer, retry, self.discovery_timeout_ms)
            except (TimeoutError, ConnectionError) as exc:
                raise RuntimeError(f"{peer.name}: proven-modern discovery retry failed") from exc
            if not isinstance(retried, dict):
                raise RuntimeError(f"{peer.name}: proven-modern discovery retry returned no result")
            retry_kind, retry_payload = decode_rpc_response(retried, retry_id)
            if retry_kind != "result":
                raise RuntimeError(f"{peer.name}: proven-modern discovery retry returned an error")
            self._activate_modern(peer, retry_payload, selected)
            return

        self._probe_legacy(peer, f"unrecognized discovery error {code}")

    def connect_all(self) -> None:
        for peer_name in sorted(self.peers):
            self._connect_peer(self.peers[peer_name])

    def _request(self, peer: Peer, method: str, params: dict[str, Any]) -> dict[str, Any]:
        request_id = self._new_id()
        if peer.era == "modern":
            message = modern_request(
                request_id,
                method,
                params,
                peer.protocol_version or PROTOCOL_VERSION,
                self.client_capabilities,

View on GitHub (pinned to 39ea8a1c6d)

Solutions

  1. Log the retry's error payload for the exact server-side reason
  2. Verify the retry request carries the same agreed version the server hinted
  3. Check server-side auth/capability requirements for discovery
  4. Restart or patch the server if the rejection is inconsistent with its own -32022 hint
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

null

Try / catch

try:
    client.connect_all()
except RuntimeError as e:
    if "discovery retry returned an error" in str(e):
        report_server_inconsistency(peer, e)

Prevention

When it happens

Trigger: decode_rpc_response(retried, retry_id) returns retry_kind='error' in the -32022 retry branch.

Common situations: Server rejecting the agreed version anyway (bug); auth or capability checks firing only on the second request; race where the server changed state between the two discovers.

Related errors


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