You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fetch(url: URL) rejects with 'Invalid URL' (cc's MCP HTTP transport passes a URL instance); a DNS failure is a plain Error without node's 'fetch failed' + cause.code #9536
for https://example.invalid/mcp (the harness's unreachable HTTP server). The SDK's StreamableHTTPClientTransport calls fetch(this._url, init) where _url is the URL instance cc constructs (client/streamableHttp.js:94/311/449).
node 26.5.1: every shape -> TypeError "fetch failed" cause: ENOTFOUND
perry main : string -> Error "Fetch error: error sending request for url (https://example.invalid/mcp)" cause: none
URL object -> Error "Invalid URL" cause: none <- the cc shape
URL + Headers -> Error "Invalid URL" cause: none
Request -> Error "Fetch error: error sending request for url (...)" cause: none
URL, signal -> Error "Invalid URL" cause: none
Two divergences, in order of weight:
fetch(URL) is rejected as Invalid URL — the URL instance is not stringified (the spec's RequestInfo is USVString | Request, and a URL converts through toString(); node, Bun and browsers all accept it). Only the string and Request forms reach the network. This is what cc hits.
The DNS-failure error shape: node rejects with TypeError whose message is exactly fetch failed and whose cause carries the node-shaped error (code: 'ENOTFOUND', syscall, hostname); perry rejects with a plain Error("Fetch error: error sending request for url (...)") and no cause. Code that branches on e.cause.code (cc does for its "(code: ..., errno: ...)" log line, retry classifiers do for ENOTFOUND/ECONNREFUSED) sees none.
Byte-compare bar: the fixture above prints node's five lines.
Closing: fixed in #9582 (fetch accepts WHATWG URL instances; transport failures reject with TypeError('fetch failed') and a cause carrying ENOTFOUND/errno/syscall/hostname), landed via merge train #9585 on 2026-09-03. Fixture test_gap_9536_fetch_url_error passes against node.
Activity
changelog: fragment for #9582 (fetch URL objects + transport errors, #…
proggeramlug commentedon Sep 3, 2026
Closing: fixed in #9582 (fetch accepts WHATWG URL instances; transport failures reject with TypeError('fetch failed') and a cause carrying ENOTFOUND/errno/syscall/hostname), landed via merge train #9585 on 2026-09-03. Fixture test_gap_9536_fetch_url_error passes against node.