microsoft/playwright · error · Error
The page has closed
Error message
The page has closed
What it means
Thrown inside the expectScreenshot polling loop when the Page becomes closed mid-wait. The screenshot matcher retries until the image stabilizes, and each iteration re-checks page liveness; a closed page cannot produce further screenshots, so the loop aborts with this message rather than timing out.
Source
Thrown at packages/playwright-core/src/server/page.ts:754
const areEqualScreenshots = (actual: Buffer | undefined, expected: Buffer | undefined, previous: Buffer | undefined) => {
const comparatorResult = actual && expected ? comparator(actual, expected, options) : undefined;
if (comparatorResult !== undefined && !!comparatorResult === !!options.isNot)
return true;
if (comparatorResult)
intermediateResult = { errorMessage: comparatorResult.errorMessage, diff: comparatorResult.diff, actual, previous };
return false;
};
let actual: Buffer | undefined;
let previous: Buffer | undefined;
const pollIntervals = [0, 100, 250, 500];
if (options.expected)
progress.log(` verifying given screenshot expectation`);
else
progress.log(` generating new stable screenshot expectation`);
let isFirstIteration = true;
while (true) {
if (this.isClosed())
throw new Error('The page has closed');
const screenshotTimeout = pollIntervals.shift() ?? 1000;
if (screenshotTimeout)
progress.log(`waiting ${screenshotTimeout}ms before taking screenshot`);
previous = actual;
actual = await rafrafScreenshot(progress, screenshotTimeout).catch(e => {
if (this.mainFrame().isNonRetriableError(e))
throw e;
progress.log(`failed to take screenshot - ` + e.message);
return undefined;
});
if (!actual)
continue;
// Compare against expectation for the first iteration.
const expectation = options.expected && isFirstIteration ? options.expected : previous;
if (areEqualScreenshots(actual, expectation, previous))
break;
if (intermediateResult)
progress.log(intermediateResult.errorMessage);View on GitHub (pinned to c8fc3bf8d3)
Solutions
- Ensure no concurrent code path closes the page while the screenshot assertion is in flight; await the assertion before calling page.close().
- Increase the page/script timeout or reduce page load so the assertion completes before any teardown.
- Wrap the assertion and treat a 'page closed' error as a signal to re-create the page, or use a scoped fixture that owns the page lifetime.
Example fix
// before
const assert = expect(page).toHaveScreenshot('x.png');
await page.close(); // races with the assertion
await assert;
// after
await expect(page).toHaveScreenshot('x.png');
await page.close(); Defensive patterns
Strategy: try-catch
Validate before calling
if (page.isClosed()) throw new Error('page already closed; skip screenshot assertion'); Try / catch
try {
await expect(page).toHaveScreenshot('home.png');
} catch (e) {
if (/page has closed/i.test(e.message)) {
// page died mid-assertion: recreate or skip rather than retry blindly
throw new Error('Screenshot assertion aborted: page closed unexpectedly');
}
throw e;
} Prevention
- Await screenshot assertions fully before any page/browser teardown.
- Avoid closing the page from concurrent async branches.
- Watch for app-level self-close (popups, window.close()) and handle them before asserting.
When it happens
Trigger: The page (or its browser) is closed, crashes, or navigates to a destroy trigger while expect(page).toHaveScreenshot() is polling; page.close() called from another async branch during the assertion; the web app calls window.close(); the browser process is killed by the OS.
Common situations: A test that closes the page in a finally block racing with a still-running screenshot assertion; an app that self-closes (popup, OAuth flow); resource exhaustion or OOM killing the browser during a heavy screenshot comparison.
Related errors
- Cannot find object to "${method}": ${guid}
- Unknown new child: ${params.guid}
- Cannot find parent object ${parentGuid} to create ${guid}
- "not" matcher requires expected result
- Browser context was closed before the daemon could start
AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12).
Data as JSON: /api/errors/9de994b9b279b166.
Report an issue: GitHub.