Skip to content

Patch playwright-core to resolve _finishedPromise on requestFailed#93802

Merged
unstubbable merged 1 commit into
canaryfrom
hl/playwright-finished-promise-patch
May 13, 2026
Merged

Patch playwright-core to resolve _finishedPromise on requestFailed#93802
unstubbable merged 1 commit into
canaryfrom
hl/playwright-finished-promise-patch

Conversation

@unstubbable

@unstubbable unstubbable commented May 12, 2026

Copy link
Copy Markdown
Contributor

The client-side BrowserContext._onRequestFailed handler in playwright-core does not resolve the corresponding Response._finishedPromise, while _onRequestFinished does. When Chromium fires Network.loadingFailed for a request that already received a response — e.g. an RSC response that was delivered to the response buffer but is no longer needed because a soft navigation has already committed — the server-side _finishedPromise is resolved correctly (in chromium/crNetworkManager._onLoadingFailed), but the client side is never told. Any caller of response.finished() on such a response hangs indefinitely, surfacing in tests as a 60s Jest timeout with no clear stack trace.

This is the root cause of intermittent timeouts in router-act-using tests.

The patch mirrors the resolve step from _onRequestFinished: look up the response via the existing async request.response() RPC and fire-and-forget resolve(null) on its _finishedPromise. catch is a no-op so a tearing-down context doesn't produce an unhandled rejection.

Verified empirically against workflow run https://github.com/vercel/next.js/actions/runs/25760869258, which flake-detected all 40 router-act consumers (each 3 times) with diagnostic logging enabled. One Network.loadingFailed canceled=true event fired during the run (the canonical bug scenario: an outer act releasing a child block: true response that Chrome canceled mid-flight; see https://github.com/vercel/next.js/actions/runs/25760869258/job/75669131568) — pre-patch this would have hung until Jest's 60s test timeout fired, post-patch response.finished() resolved in 1ms. Alongside ~4000 normal resolutions, with zero wait-browser-finished hangs and zero router-act-related test failures.

This is a stop-gap until the router-act rewrite in #90959 lands, which replaces Playwright's route.fulfill + response.finished() flow with a browser-side fetch interception and removes the dependency on this Playwright code path entirely. The patch can be dropped at that point.

The client-side `BrowserContext._onRequestFailed` handler in
`playwright-core` does not resolve the corresponding
`Response._finishedPromise`, while `_onRequestFinished` does. When
Chromium fires `Network.loadingFailed` for a request that already
received a response — e.g. an RSC response that was delivered to the
response buffer but is no longer needed because a soft navigation has
already committed — the server-side `_finishedPromise` is resolved
correctly (in `chromium/crNetworkManager._onLoadingFailed`), but the
client side is never told. Any caller of `response.finished()` on
such a response hangs indefinitely, surfacing in tests as a 60s Jest
timeout with no clear stack trace.

This is the root cause of intermittent timeouts in router-act-using
tests.

The patch mirrors the resolve step from `_onRequestFinished`: look up
the response via the existing async `request.response()` RPC and
fire-and-forget `resolve(null)` on its `_finishedPromise`. `catch`
is a no-op so a tearing-down context doesn't produce an unhandled
rejection.

Verified empirically against workflow run
https://github.com/vercel/next.js/actions/runs/25760869258, which
flake-detected all 40 router-act consumers (each 3 times) with
diagnostic logging enabled. One `Network.loadingFailed canceled=true`
event fired during the run (the canonical bug scenario: an outer
`act` releasing a child `block: true` response that Chrome canceled
mid-flight; see
https://github.com/vercel/next.js/actions/runs/25760869258/job/75669131568)
— pre-patch this would have hung until Jest's 60s test timeout
fired, post-patch `response.finished()` resolved in 1ms. Alongside
~4000 normal resolutions, with zero `wait-browser-finished` hangs
and zero router-act-related test failures.

This is a stop-gap until the router-act rewrite in #90959 lands, which
replaces Playwright's `route.fulfill` + `response.finished()` flow
with a browser-side `fetch` interception and removes the dependency
on this Playwright code path entirely. The patch can be dropped at
that point.
@unstubbable unstubbable changed the title hl/playwright finished promise patch Patch playwright-core to resolve _finishedPromise on requestFailed May 12, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Tests Passed

Commit: c70f628

@unstubbable unstubbable marked this pull request as ready for review May 12, 2026 22:32
@unstubbable unstubbable requested a review from acdlite May 12, 2026 22:37
@lubieowoce

Copy link
Copy Markdown
Member

damn, nice find

@unstubbable unstubbable merged commit 7c6f9e7 into canary May 13, 2026
164 of 165 checks passed
@unstubbable unstubbable deleted the hl/playwright-finished-promise-patch branch May 13, 2026 11:46
lubieowoce pushed a commit that referenced this pull request May 13, 2026
Reverts #92199.

Depends on #93802, which patches `playwright-core` to fix the root
cause: the client-side `Response._finishedPromise` was never resolved on
`requestFailed`, causing `response.finished()` to hang indefinitely and
surface as opaque 60s Jest timeouts in router-act-using tests.

With that patch in place, the cached-navigations tests can be
reinstated. This PR's CI is part of the verification path — the
previously-flaky tests now run cleanly through the 3× flake-detection
job.

<!-- NEXT_JS_LLM_PR -->
unstubbable added a commit that referenced this pull request May 18, 2026
@github-actions github-actions Bot locked as resolved and limited conversation to collaborators May 27, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants