{"record":{"id":"693d3c8deb8aad28","repo":"PrefectHQ/fastmcp","slug":"invalid-url-url","errorCode":null,"errorMessage":"Invalid URL: {url}","messagePattern":"Invalid URL: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/mcp_config.py","lineNumber":63,"sourceCode":"if TYPE_CHECKING:\n    from fastmcp.client.transports import (\n        ClientTransport,\n        FastMCPTransport,\n        SSETransport,\n        StdioTransport,\n        StreamableHttpTransport,\n    )\n\n\ndef infer_transport_type_from_url(\n    url: str | AnyUrl,\n) -> Literal[\"http\", \"sse\"]:\n    \"\"\"\n    Infer the appropriate transport type from the given URL.\n    \"\"\"\n    url = str(url)\n    if not url.startswith(\"http\"):\n        raise ValueError(f\"Invalid URL: {url}\")\n\n    parsed_url = urlparse(url)\n    path = parsed_url.path\n\n    # Match /sse followed by /, ?, &, or end of string\n    if re.search(r\"/sse(/|\\?|&|$)\", path):\n        return \"sse\"\n    else:\n        return \"http\"\n\n\ndef _coerce_tool_transform_configs(tools: dict[str, Any]) -> dict[str, Any]:\n    from fastmcp.tools.tool_transform import ToolTransformConfig\n\n    return {\n        name: config\n        if isinstance(config, ToolTransformConfig)\n        else ToolTransformConfig.model_validate(config)","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/mcp_config.py#L45-L81","documentation":"infer_transport_type_from_url only accepts HTTP(S) URLs, since it exists to pick between the 'http' (streamable) and 'sse' MCP transports, both of which require an http/https endpoint. If the string does not start with 'http', it raises ValueError('Invalid URL: ...'). This catches typos like forgetting the scheme entirely.","triggerScenarios":"Passing a URL like 'localhost:8000/mcp' (no scheme), 'ftp://host/sse', or a bare hostname/path to infer_transport_type_from_url, infer_transport, or an MCPConfig server entry with an http_url-based remote server lacking an http(s) URL.","commonSituations":"Copy-pasting a server address from docs that omits 'https://'; building the URL from env vars where the scheme variable is empty; hand-editing .mcp.json entries.","solutions":["Prepend the scheme: use 'https://host/path' (or http:// for local dev)","Validate the URL with urlparse before calling","Check the config file entry actually contains a full URL, not a host:port pair"],"exampleFix":"// before\ntransport = infer_transport(\"localhost:8000/mcp\")\n// after\ntransport = infer_transport(\"https://localhost:8000/mcp\")","handlingStrategy":"validation","validationCode":"from urllib.parse import urlparse\ndef is_valid_http_url(url) -> bool:\n    u = urlparse(str(url))\n    return u.scheme in (\"http\", \"https\") and bool(u.netloc)","typeGuard":"def is_http_url(v: object) -> bool:\n    try:\n        u = urlparse(str(v))\n    except ValueError:\n        return False\n    return u.scheme in (\"http\", \"https\") and bool(u.netloc)","tryCatchPattern":null,"preventionTips":["Always include the scheme in server URLs in .mcp.json","Lint config files for URLs missing http(s)://","Build URLs with helpers that assert the scheme"],"tags":["config","url","validation","mcp"],"backgroundTag":"invalid-url","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}