Skip to content

fix(resolver): keep HTTP status when copying guarded responses - #4308

Open
robert-hebel-sb wants to merge 1 commit into
mainfrom
fix/http-resolver-response-status
Open

robert-hebel-sb wants to merge 1 commit into
mainfrom
fix/http-resolver-response-status

Conversation

@robert-hebel-sb

Copy link
Copy Markdown
Contributor

In browsers, fetch returns responses whose headers can't be mutated. The ApiDOM HTTP resolver (HTTPResolverSwaggerClient) therefore copies the response to remove its Content-Type. The copy spread the response into the Response init, but status, statusText and url are getters of Response.prototype, so the spread copied none of them.

As a result, every external document retrieved in a browser became a 200 OK. A 404 page was parsed as the referenced document, and no resolver error was reported. In Node.js, undici lets the headers be mutated, so the bug only shows in browsers. It affects every ApiDOM-based strategy (OpenAPI 3.1 and 3.2).

Fix: copy status and statusText explicitly. Keep the response URL as an own property of the copy, since the Response constructor can't set it, so responseInterceptor sees the same status and final URL as in Node.js.

Tests: the resolver now reads guarded responses (browser-like headers): a 200, a 404 that must fail, responseInterceptor receiving status and URL, and an OpenAPI 3.1 external $ref to a 404 that must report an error. Three of them fail on main.

Found by Swagger UI while testing external $refs in Chromium.

🤖 Generated with Claude Code

Browsers return fetch responses whose headers can't be mutated, so the
ApiDOM HTTP resolver copies the response to remove its Content-Type. The
copy spread the response into the Response init, but status, statusText and
url are getters of Response.prototype, so every external document retrieved
in a browser became a 200 OK: a 404 page was parsed as the referenced
document and no resolver error was reported. This affects every
ApiDOM-based strategy (OpenAPI 3.1 and 3.2).

Copy status and statusText explicitly and keep the response URL as an own
property of the copy, which the Response constructor can't set, so
responseInterceptor sees the same response as in Node.js.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants