microsoft/playwright · error · Error
Cannot set cookies without an open page
Error message
Cannot set cookies without an open page
What it means
On the iOS Safari webview backend, cookie operations are scoped to an open page (the WKWebView only exposes document.cookie for the current page's domain). addCookies needs that page to inject cookies via the page protocol; with zero pages attached there is nowhere to write, so it throws. doGetCookies returns [] in the same situation, but addCookies cannot silently no-op.
Source
Thrown at packages/playwright-core/src/server/webkit/webview/wvBrowser.ts:337
return network.filterCookies(cookies.map(c => {
const copy: channels.NetworkCookie = {
name: c.name,
value: c.value,
domain: c.domain,
path: c.path,
expires: c.session ? -1 : c.expires / 1000,
httpOnly: c.httpOnly,
secure: c.secure,
sameSite: c.sameSite,
};
return copy;
}), urls);
}
async addCookies(cookies: channels.SetNetworkCookie[]) {
const page = this._cookiePage();
if (!page)
throw new Error('Cannot set cookies without an open page');
const protocolCookies = network.rewriteCookies(cookies).map(c => {
const session = c.expires === undefined || c.expires === -1;
const cookie: Protocol.Page.Cookie = {
name: c.name,
value: c.value,
domain: c.domain!,
path: c.path!,
expires: session ? 0 : c.expires! * 1000,
session,
httpOnly: !!c.httpOnly,
secure: !!c.secure,
sameSite: c.sameSite ?? 'Lax',
};
return cookie;
});
await page.setCookies(protocolCookies);
}
View on GitHub (pinned to c8fc3bf8d3)
Solutions
- Ensure at least one page is open (context.pages().length > 0) before calling addCookies on a webview context.
- Navigate the existing page to the target domain first, then addCookies, then continue.
- If the page closed, reconnect or have the user reopen Safari before setting cookies.
Example fix
// before
await context.addCookies([{ name: 'sid', value: '1', domain: 'example.com', path: '/' }]);
// throws if no page attached
// after
const page = context.pages()[0];
if (page) {
await page.goto('https://example.com');
await context.addCookies([{ name: 'sid', value: '1', domain: 'example.com', path: '/' }]);
} Defensive patterns
Strategy: validation
Validate before calling
function assertPageForCookies(context) {
if (!context.pages().length) throw new Error('Open a page before adding cookies on a webview context.');
}
assertPageForCookies(context);
await context.addCookies(cookies); Try / catch
try { await context.addCookies(cookies); }
catch (e) {
if (/without an open page/i.test(String(e.message))) {
await context.pages()[0]?.goto(targetUrl);
await context.addCookies(cookies);
} else throw e;
} Prevention
- Ensure context.pages().length > 0 before addCookies on webview.
- Navigate the existing page to the target domain before setting cookies.
- Don't close the page before setting up cookies for the next test.
When it happens
Trigger: Calling context.addCookies([...]) on a webview context after all tabs/pages have closed (or before any page is attached); calling addCookies right after connect when the single tab detached.
Common situations: A test that sets up cookies before navigating, against an iOS Safari session where the initial tab disappeared; teardown ordering that closes the page before cookie setup of the next test.
Related errors
- Not supported
- Method not implemented.
- SyncServer: failed to bind HTTP server
- ios_webkit_debug_proxy ${proxyBase}/json returned ${res.stat
- No Mobile Safari tabs found at ${this._proxyBase}/json — ope
AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12).
Data as JSON: /api/errors/8e895e554b051825.
Report an issue: GitHub.