Playwright: Target page, context or browser has been closed
Last verified
Error: page.goto: Target page, context or browser has been closedWhat it means
A call was made on a page, browser context or browser that no longer exists. Playwright raises this TargetClosedError for any API whose target was closed before or during the call, so the method name in front changes (page.goto, locator.click, page.waitForTimeout) but the cause is the same: something closed the object you were still using.
Very often the closer is your own code. In Node.js, the most common source is a missing await: the action is still running when the test ends or browser.close() runs, and the pending call then fails with this message. In Playwright Test, it also appears as the secondary error after a test timeout, because the runner tears down the page while your step is still waiting.
What is not wrong: the selector or URL. Look earlier in the output for the real failure; this message is frequently the second error, not the first.
What it looks like
// Bug: no await, so the test ends while click is pending
test('saves', async ({ page }) => {
await page.goto('https://example.com/form');
page.getByRole('button', { name: 'Save' }).click(); // missing await
});
// Fixed
test('saves', async ({ page }) => {
await page.goto('https://example.com/form');
await page.getByRole('button', { name: 'Save' }).click();
await expect(page.getByText('Saved')).toBeVisible();
});Why it happens
- A missing await lets the test or script finish while an action is still pending.
- browser.close(), context.close() or page.close() runs in a finally block or hook before outstanding work completes.
- The test exceeded its timeout and the runner closed the page; this error is then reported alongside 'Test timeout of 30000ms exceeded.'
- The browser process crashed, often from running out of memory or /dev/shm space in a container.
- The site itself closed the tab, for example a popup that calls window.close() after login.
How to fix it
- Scroll up in the report: if a test timeout or another error precedes this one, fix that first.
- Enable the @typescript-eslint/no-floating-promises lint rule and add await to every Playwright call it flags.
- Move cleanup so it runs only after all actions have resolved; in Playwright Test let fixtures close pages instead of closing them manually.
- If you interact with a popup, capture it with const popup = await page.waitForEvent('popup') and stop using it once it closes.
- In Docker, launch with --ipc=host or a larger --shm-size, or pass args: ['--disable-dev-shm-usage'], to avoid Chromium crashes.
How to stop it recurring
Let the runner own the lifecycle: use the built-in page and context fixtures rather than launching and closing browsers by hand. Lint for floating promises so a forgotten await fails code review instead of a nightly run. In containers, use the official Playwright Docker image with --ipc=host, and listen for page.on('crash') to distinguish crashes from code-level closes.
Official documentation: playwright.dev/docs/api/class-page#page-event-close. See all Playwright error messages.
Related errors
Definitions
- PlaywrightPlaywright is Microsoft's open-source browser automation framework that provides a single API to control Chrom
- Chrome DevTools Protocol (CDP)The Chrome DevTools Protocol (CDP) is the JSON-over-WebSocket interface Chrome exposes for inspecting and cont
- CSS SelectorA CSS selector is a pattern used to identify and target specific HTML elements on a web page, widely used in b
- Headless ChromeHeadless Chrome is Google Chrome running without a visible window. It renders pages and runs JavaScript like n
- IframeAn iframe (inline frame) is an HTML element that embeds a separate web page within a parent page, creating an
- Web ElementA web element is any individual component rendered on a web page — buttons, links, input fields, images, text
Quick answers
What does "Target page, context or browser has been closed" mean in Playwright?
A call was made on a page, browser context or browser that no longer exists. Playwright raises this TargetClosedError for any API whose target was closed before or during the call, so the method name in front changes ( page.goto , locator.click , page.waitForTimeout ) but the cause is the same: something closed the object you were still using. Very often the closer is your own code.
How do I fix "Target page, context or browser has been closed"?
1. Scroll up in the report: if a test timeout or another error precedes this one, fix that first. 2. Enable the @typescript-eslint/no-floating-promises lint rule and add await to every Playwright call it flags. 3. Move cleanup so it runs only after all actions have resolved; in Playwright Test let fixtures close pages instead of closing them manually. 4. If you interact with a popup, capture it with const popup = await page.waitForEvent('popup') and stop using it once it closes. 5. In Docker, launch with --ipc=host or a larger --shm-size, or pass args: ['--disable-dev-shm-usage'], to avoid…
Run browser automation you can watch and take over
Autonoly runs each job in a real cloud Chromium browser driven by Playwright. Timeouts and detached elements still happen; the difference is that you can watch the run live, see the step that failed, and take control of the browser to finish it.
Also see Live browser control.