Skip to content

Node.js 24.16.0: Playwright browser context teardown hangs (regression from 24.15.0) #63495

@anshprat

Description

@anshprat

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:

  1. A Playwright test suite using @playwright/test v1.58.2
  2. Config with video: "on", trace: "on", screenshot: "on"
  3. Tests that use page.goto(), page.waitForLoadState("networkidle"), and standard Playwright assertions
  4. 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:

  1. Test body completes in 7–20s (assertions pass)
  2. Playwright's list reporter prints the test result line (with the body duration)
  3. Browser context teardown hangs — the worker is blocked for the remaining test timeout budget
  4. After the full test timeout (30s or 60s) fires, Playwright forcefully kills the test
  5. Error reported: Test timeout of 30000ms exceeded. with no stack trace (indicating the hang is in implicit teardown, not user code)
  6. ~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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions