{"record":{"id":"27c1dac43fc48aa9","repo":"PrefectHQ/fastmcp","slug":"mode-must-be-legacy-auto-or-one-of-list-mod","errorCode":null,"errorMessage":"mode must be 'legacy', 'auto', or one of {list(MODERN_PROTOCOL_VERSIONS)}; got {mode!r}{hint}","messagePattern":"mode must be 'legacy', 'auto', or one of (.+?); got (.+?)(.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/client/client.py","lineNumber":456,"sourceCode":"        verify: ssl.SSLContext | bool | str | None = None,\n        mode: ConnectMode = \"auto\",\n        prior_discover: mcp_types.DiscoverResult | None = None,\n        input_required_max_rounds: int = DEFAULT_INPUT_REQUIRED_MAX_ROUNDS,\n        cache: CacheConfig | bool | None = None,\n        extensions: Sequence[ClientExtension] | None = None,\n        result_claims: Mapping[str, Sequence[ResultClaim[Any]]] | None = None,\n    ) -> None:\n        self.name = name or self.generate_name()\n\n        self.input_required_max_rounds = input_required_max_rounds\n\n        if mode not in (\"legacy\", \"auto\") and mode not in MODERN_PROTOCOL_VERSIONS:\n            hint = (\n                f\" ({mode!r} is a handshake-era version; use mode='legacy')\"\n                if mode in HANDSHAKE_PROTOCOL_VERSIONS\n                else \"\"\n            )\n            raise ValueError(\n                \"mode must be 'legacy', 'auto', or one of \"\n                f\"{list(MODERN_PROTOCOL_VERSIONS)}; got {mode!r}{hint}\"\n            )\n        self.mode: ConnectMode = mode\n        self._prior_discover = prior_discover\n\n        self.transport = cast(ClientTransportT, infer_transport(transport))\n\n        if verify is not None:\n            from fastmcp.client.transports.http import StreamableHttpTransport\n            from fastmcp.client.transports.sse import SSETransport\n\n            if isinstance(self.transport, StreamableHttpTransport | SSETransport):\n                self.transport.verify = verify\n                # Re-sync existing OAuth auth with the new verify setting,\n                # but only if the transport doesn't have a custom factory\n                # (which takes precedence and was already applied to OAuth).\n                if (","sourceCodeStart":438,"sourceCodeEnd":474,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/client/client.py#L438-L474","documentation":"Client.__init__ validates the mode parameter: it must be 'legacy', 'auto', or one of the modern protocol version strings in MODERN_PROTOCOL_VERSIONS. Anything else — including handshake-era version dates like '2025-03-26' — raises this ValueError; handshake-era values get an explicit hint to use mode='legacy'.","triggerScenarios":"Passing mode=<anything not in {'legacy','auto'} ∪ MODERN_PROTOCOL_VERSIONS> to Client(...) or Client.new(...) — e.g. mode='2025-03-26' (handshake-era), mode='v4', mode=None, or a typo like mode='Legacy'.","commonSituations":"Copying a protocol date string from older MCP docs/examples; trying to pin a pre-modern protocol version; casing or spelling mistakes in 'legacy'/'auto'.","solutions":["Use mode='auto' (default) or mode='legacy'.","To pin a version, use one of the strings listed in the error message (values of MODERN_PROTOCOL_VERSIONS).","If you passed a handshake-era date, replace it with mode='legacy' as the hint suggests.","Check spelling/casing of the mode value."],"exampleFix":"// before: handshake-era version pin rejected\nclient = Client(url, mode='2025-03-26')\n// after\nclient = Client(url, mode='legacy')","handlingStrategy":"validation","validationCode":"from fastmcp.client.client import MODERN_PROTOCOL_VERSIONS\nmode = '2025-03-26'\nassert mode in ('legacy', 'auto', *MODERN_PROTOCOL_VERSIONS), f'invalid mode: {mode!r}'","typeGuard":"from typing import Literal\nfrom fastmcp.client.client import MODERN_PROTOCOL_VERSIONS\nValidMode = Literal['legacy', 'auto'] | str\ndef is_valid_mode(mode: ValidMode) -> bool:\n    return mode in ('legacy', 'auto') or mode in MODERN_PROTOCOL_VERSIONS","tryCatchPattern":"try:\n    client = Client(url, mode=mode)\nexcept ValueError as e:\n    if 'mode must be' in str(e):\n        mode = 'legacy'  # or a listed modern version\n        client = Client(url, mode=mode)\n    else:\n        raise","preventionTips":["Only pass 'auto' (default), 'legacy', or a version string printed in the error (MODERN_PROTOCOL_VERSIONS).","Never pin handshake-era protocol dates via mode; use mode='legacy' for those servers.","Type-annotate mode as ConnectMode and validate config-sourced values at load time.","Copy allowed values from the library, not from old documentation examples."],"tags":["validation","configuration","arguments","client"],"backgroundTag":"invalid-argument-value","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}