Repository navigation
Description
Follow-up from the v2.7.0 release-candidate smoke (ledger), where #2319 was the one row that could not be driven and had to ship as a caveat.
What is missing
#2319 put AbortSignal.timeout on five OAuth-path calls that previously went out with no signal at all:
| Call | Endpoint |
|---|---|
| Protected-resource-metadata discovery | /.well-known/oauth-protected-resource |
| Authorization-server metadata discovery | /.well-known/oauth-authorization-server |
| Dynamic client registration | /register |
| Token exchange | /token |
| Refresh | /token |
No fixture can make any of them fire. The composable test server's oauth block has no stall, delay or never-answer capability — the full option list is asMetadataPath, issuerUrl, accessTokenIssuers, jwksUri, resourceAudience, scopesSupported, requireAuth, staticClients, supportDCR, supportCIMD, clientMetadata, clientMetadataPath, tokenExpirationSeconds, supportRefreshTokens, supportRevocation. Every one of them answers promptly by construction.
So the timeouts are covered by unit tests that inject a fetch stub, and by nothing that exercises the real Node-side socket. That is precisely the shape #2319 says matters:
It runs server-side, in the Inspector's own Node process, proxied through the backend. So a stall is invisible in browser devtools […] while a Node-side socket sat established and idle.
A stub cannot reproduce an established, idle socket. Only a server that accepts and withholds can.
Proposed
Add a stall capability to the composable server's oauth block:
"oauth": {
"enabled": true,
"requireAuth": true,
// Accept the request and withhold the response, per endpoint.
"stallEndpoints": ["token"],
// Optional: answer after N ms instead of never. Omitted = hold until the
// client gives up or the server stops.
"stallMs": 0
}plus a showcase config (oauth-stalled-token-http.json) and a row in docs/test-servers.md saying what it does and what the broken build looked like.
Two constraints worth stating up front, because they are where this gets fiddly:
- A withheld response must not block server shutdown. The stalled handler has to be released on stop, or every suite using the fixture hangs at teardown instead of failing cleanly.
- Per-endpoint, not global. A server that stalls everything cannot distinguish "discovery timed out" from "token exchange timed out", which is the distinction the five timeouts exist to make.
Why now
This is the fixture that would let the release smoke drive #2319 end to end instead of recording it as unverified. It is test infrastructure, so it changes no shipped behavior — but it is what turns five timeouts from "asserted against a stub" into "observed against a socket".
Activity
cliffhall commentedon Sep 16, 2026
Triage: Priority Medium (total 6)
bugor security label, no engagement, not a sub-issue, and the milestone bonus does not apply to an issue filed through the create flowBoard: #28, Status
In Progress(picked up immediately as part of the v2.7.0 release verification).feat(test-servers): stall an OAuth endpoint so #2319's timeouts can b…
cliffhall commentedon Sep 16, 2026
Shipped in #2383, squash-merged to
v2/main.