How to fix Playwright "Target page, context or browser has been closed" after crashes?

Playwright

When this error appears alongside a crash — rather than an orderly context.close() call — it means the browser process exited unexpectedly and Playwright's pending actions found their target gone. The Playwright TargetClosedError surfaces as Error: locator.click: Target page, context or browser has been closed with no preceding graceful teardown in the test. In CI this is almost always a resource exhaustion problem: too many parallel workers consuming more memory than the container allows, the Linux sandbox killing a Chromium child process, or missing OS-level dependencies causing the browser to abort on startup. This is distinct from the early teardown variant where code explicitly closes context before finishing.

Common mistake

// playwright.config.ts — no worker limit in CI, no retries
export default defineConfig({
  fullyParallel: true,
  // workers defaults to logical CPU count — can be 32+ on cloud runners
});

Running with the default worker count on a container that has 2 GB of memory and 32 logical CPUs will consistently OOM-kill browser processes, producing a stream of TargetClosedError failures.

The fix

Reduce parallelism in CI, enable retries, and capture traces on first retry to diagnose the exact failure:

import { defineConfig } from '@playwright/test';

export default defineConfig({
  retries: process.env.CI ? 2 : 0,
  workers: process.env.CI ? 2 : undefined,
  use: {
    trace: 'on-first-retry',
    video: 'on-first-retry',
  },
  reporter: process.env.CI ? 'github' : 'list',
});

For Docker/Kubernetes environments, add the --disable-dev-shm-usage Chromium argument and ensure the container has sufficient shared memory:

export default defineConfig({
  use: {
    launchOptions: {
      args: ['--disable-dev-shm-usage'],
    },
  },
});

Or mount a larger /dev/shm in your Docker run command:

docker run --shm-size=2gb your-playwright-image npx playwright test

For CI pipelines where browser crashes happen only on specific suites, enable per-suite tracing to identify which test triggered the crash:

test.use({ trace: 'on' });

Why it works

Chromium spawns multiple renderer processes per context, each requiring shared memory for GPU compositing. On Linux, Chromium defaults to using /dev/shm for this, which is typically only 64 MB in Docker containers. When /dev/shm is exhausted, the renderer process is OOM-killed, producing a TargetClosedError in Playwright. --disable-dev-shm-usage redirects shared memory to /tmp, which uses the container's main memory allocation. Reducing workers lowers the peak memory footprint per CI job.

Tips

  • Check CI runner logs for OOM killer messages (Out of memory: Kill process) alongside the Playwright error — this confirms the crash is memory-related.
  • For Kubernetes-hosted CI, set both requests.memory and limits.memory high enough for your worker count — 1.5 GB per browser worker is a reasonable baseline.
  • If the error appears after a specific test rather than randomly, the test may be leaking browser instances — verify all context.close() calls are properly awaited in afterAll hooks.
  • For the non-crash variant of this error where context is closed by code too early, see target page context or browser has been closed.