Version
v24.16.0
Platform
Linux (x64 and arm64), self-hosted CI runners
Subsystem
streams, async
What steps will reproduce the bug?
Run any Playwright E2E test suite with video: "on" and trace: "on" under Node.js 24.16.0. After the test body completes (all assertions pass), the browser context teardown hangs indefinitely until the test timeout fires.
Minimal reproduction setup:
- A Playwright test suite using
@playwright/test v1.58.2
- Config with
video: "on", trace: "on", screenshot: "on"
- Tests that use
page.goto(), page.waitForLoadState("networkidle"), and standard Playwright assertions
- A
webServer configuration launching a Vite dev server
// playwright.config.ts (relevant parts)
export default defineConfig({
webServer: {
command: "pnpm dev",
url: "http://localhost:4040",
reuseExistingServer: false,
timeout: 120_000,
},
retries: 1,
workers: Math.max(1, Math.floor(os.cpus().length * 0.35)),
expect: { timeout: 0 },
use: {
baseURL: "http://localhost:4040",
headless: true,
viewport: { width: 1280, height: 720 },
trace: "on",
video: "on",
screenshot: "on",
},
});
How often does it reproduce? Is there a required condition?
100% reproducible on Node.js 24.16.0. Works perfectly on 24.15.0.
Tested across:
- Multiple independent feature branches (no code changes between green/red runs)
- Both x64 and arm64 Linux runners
- Over 50 CI runs on May 22, all failing; all runs on May 21 (Node 24.15.0) passing
What is the expected behavior? Why is that the expected behavior?
Tests should complete normally — the test body finishes, fixture teardown runs, browser context closes, video/trace files are finalized, and the test is marked as passed. This is the behavior on Node.js 24.15.0.
What do you see instead?
On Node.js 24.16.0:
- Test body completes in 7–20s (assertions pass)
- Playwright's list reporter prints the test result line (with the body duration)
- Browser context teardown hangs — the worker is blocked for the remaining test timeout budget
- After the full test timeout (30s or 60s) fires, Playwright forcefully kills the test
- Error reported: Test timeout of 30000ms exceeded. with no stack trace (indicating the hang is in implicit teardown, not user code)
- ~30–60s gap between test batches (matching timeout value) as workers are stuck in teardown
Timing comparison (same test suite, same tests):
┌──────────────┬───────────┬─────────────────┬────────────┐
│ Node Version │ Test Body │ Total Test Time │ Result │
├──────────────┼───────────┼─────────────────┼────────────┤
│ 24.15.0 │ 16.4s │ ~16.4s │ ✅ Pass │
├──────────────┼───────────┼─────────────────┼────────────┤
│ 24.16.0 │ 17.8s │ 60.0s (timeout) │ ❌ Timeout │
└──────────────┴───────────┴─────────────────┴────────────┘
The test body duration is nearly identical — the regression is entirely in the teardown phase.
Desktop Electron-based E2E tests (which don't use Playwright's webServer or Vite dev server) are unaffected and continue to pass on 24.16.0.
Additional information
This is likely related to #63487 (extract-zip hanging in 24.16.0). Both issues point to async/stream handling regressions in 24.16.0 — different code paths but potentially
the same underlying cause.
The v24.16.0 changelog mentions "destruction propagation in duplexPair"h could affect how Playwright's CDP WebSocket connection (used forbrowser communication, video recording, and trace collection) is torn down.
Workaround: Pin NODE_VERSION to 24.15.0 in CI configuration.
Version
v24.16.0
Platform
Linux (x64 and arm64), self-hosted CI runners
Subsystem
streams, async
What steps will reproduce the bug?
Run any Playwright E2E test suite with
video: "on"andtrace: "on"under Node.js 24.16.0. After the test body completes (all assertions pass), the browser context teardown hangs indefinitely until the test timeout fires.Minimal reproduction setup:
@playwright/testv1.58.2video: "on",trace: "on",screenshot: "on"page.goto(),page.waitForLoadState("networkidle"), and standard Playwright assertionswebServerconfiguration launching a Vite dev serverHow often does it reproduce? Is there a required condition?
100% reproducible on Node.js 24.16.0. Works perfectly on 24.15.0.
Tested across:
What is the expected behavior? Why is that the expected behavior?
Tests should complete normally — the test body finishes, fixture teardown runs, browser context closes, video/trace files are finalized, and the test is marked as passed. This is the behavior on Node.js 24.15.0.
What do you see instead?
On Node.js 24.16.0:
Timing comparison (same test suite, same tests):
┌──────────────┬───────────┬─────────────────┬────────────┐
│ Node Version │ Test Body │ Total Test Time │ Result │
├──────────────┼───────────┼─────────────────┼────────────┤
│ 24.15.0 │ 16.4s │ ~16.4s │ ✅ Pass │
├──────────────┼───────────┼─────────────────┼────────────┤
│ 24.16.0 │ 17.8s │ 60.0s (timeout) │ ❌ Timeout │
└──────────────┴───────────┴─────────────────┴────────────┘
The test body duration is nearly identical — the regression is entirely in the teardown phase.
Desktop Electron-based E2E tests (which don't use Playwright's webServer or Vite dev server) are unaffected and continue to pass on 24.16.0.
Additional information
This is likely related to #63487 (extract-zip hanging in 24.16.0). Both issues point to async/stream handling regressions in 24.16.0 — different code paths but potentially
the same underlying cause.
The v24.16.0 changelog mentions "destruction propagation in duplexPair"h could affect how Playwright's CDP WebSocket connection (used forbrowser communication, video recording, and trace collection) is torn down.
Workaround: Pin NODE_VERSION to 24.15.0 in CI configuration.