How to fix Playwright "Target page, context or browser has been closed" after crashes?
PlaywrightWhen 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.