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

{peer.name}: no mutually supported modern version

Error message

{peer.name}: no mutually supported modern version

What it means

Discovery succeeded and advertised versions, but none of them intersect with the versions this client can speak, so _mutual_version returned None. The client will not pretend to speak a version it does not support.

Source

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

        except (TimeoutError, ConnectionError) as exc:
            self._probe_legacy(peer, type(exc).__name__)
            return

        if response is None:
            self._probe_legacy(peer, "empty discovery response")
            return
        if not isinstance(response, dict):
            raise RuntimeError(f"{peer.name}: malformed discovery response")
        kind, payload = decode_rpc_response(response, request_id)
        if kind == "result":
            advertised = payload.get("supportedVersions", [])
            if not isinstance(advertised, list) or not all(
                isinstance(version, str) for version in advertised
            ):
                raise RuntimeError(f"{peer.name}: malformed modern discovery result")
            selected = self._mutual_version(advertised)
            if selected is None:
                raise RuntimeError(f"{peer.name}: no mutually supported modern version")
            self._activate_modern(peer, payload, selected)
            return

        code = payload["code"]
        if code in RECOGNIZED_MODERN_ERRORS:
            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,

View on GitHub (pinned to 39ea8a1c6d)

Solutions

  1. Compare the server's advertised versions with the client's supported set
  2. Upgrade the client's supported version list to include the server's revision
  3. Downgrade or reconfigure the server to advertise a common version

Example fix

// before
client = McpClient(..., supported_modern={"2.0"})
# server advertises ["2.1"]

// after
client = McpClient(..., supported_modern={"2.0", "2.1"})
Defensive patterns

Strategy: validation

Validate before calling

adv = probe_supported_versions(peer)
if not set(adv) & client.supported_modern:
    widen_client_versions_or_upgrade_server(client, peer)

Type guard

null

Try / catch

try:
    client.connect_all()
except RuntimeError as e:
    if "no mutually supported modern version" in str(e):
        reconcile_version_sets(client, peer)

Prevention

When it happens

Trigger: _mutual_version(advertised) returns None: every entry in the server's supportedVersions list is absent from the client's supported modern versions.

Common situations: Major version skew after a server upgrade; client pinned to an old revision set; server advertising only prerelease versions the client excludes.

Related errors


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