rohitg00/ai-engineering-from-scratch · error · RuntimeError
{peer.name}: proven-modern discovery retry failed
Error message
{peer.name}: proven-modern discovery retry failed What it means
After a -32022 version hint proved a common version exists, the client resent server/discover with that version and the transport raised TimeoutError or ConnectionError. The retry is bounded by discovery_timeout_ms and fails closed rather than looping.
Source
Thrown at phases/13-tools-and-protocols/08-building-an-mcp-client/code/main.py:457
if code != -32022:
raise RuntimeError(f"{peer.name}: correct modern request error {code} before retrying")
data = payload.get("data")
advertised = data.get("supported", []) if isinstance(data, dict) else []
selected = self._mutual_version(advertised)
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(View on GitHub (pinned to 39ea8a1c6d)
Solutions
- Increase discovery_timeout_ms
- Check peer health and connection stability between the two discovery round trips
- Look at server logs for a crash or deadlock triggered by the versioned retry
- Re-run connect_all once transient network issues are ruled out
Example fix
// before client = McpClient(..., discovery_timeout_ms=1000) // after client = McpClient(..., discovery_timeout_ms=8000)
Defensive patterns
Strategy: retry
Validate before calling
if peer_rtt(peer) > client.discovery_timeout_ms:
client.discovery_timeout_ms = peer_rtt(peer) * 4 Type guard
null
Try / catch
try:
client.connect_all()
except RuntimeError as e:
if "discovery retry failed" in str(e) and transient: # after fixing cause
client.connect_all() Prevention
- Budget discovery_timeout_ms for two round trips, not one
- Watch for connection resets between paired requests
When it happens
Trigger: self._send(peer, retry, self.discovery_timeout_ms) inside the -32022 retry path raises TimeoutError or ConnectionError.
Common situations: Server accepting the first request then stalling on the retry; connection reset between the two discovery calls; discovery_timeout_ms too tight for a loaded server.
Related errors
- {peer.name}: bounded legacy probe failed closed
- server/discover accepts no params beyond _meta
- {peer.name}: malformed discovery response
- {peer.name}: malformed modern discovery result
- {peer.name}: no mutually supported modern version
AI-assisted analysis of rohitg00/ai-engineering-from-scratch@39ea8a1c6d (2026-08-26).
Data as JSON: /api/errors/e93114c41aac0056.
Report an issue: GitHub.