microsoft/playwright · error · Error
PDF generation is only supported for Headless Chromium
Error message
PDF generation is only supported for Headless Chromium
What it means
page.pdf() is implemented only by the Chromium browser backend and only in headless mode. The dispatcher checks `this._page.pdf` (a delegate method that is undefined on Firefox/WebKit pages) and throws when it is absent. This is a hard backend-capability limitation, not a configuration toggle.
Source
Thrown at packages/playwright-core/src/server/dispatchers/pageDispatcher.ts:339
async mouseUp(params: channels.PageMouseUpParams, progress: Progress): Promise<void> {
await this._page.mouse.apiUp(progress, params);
}
async mouseClick(params: channels.PageMouseClickParams, progress: Progress): Promise<void> {
await this._page.mouse.apiClick(progress, params.x, params.y, params);
}
async mouseWheel(params: channels.PageMouseWheelParams, progress: Progress): Promise<void> {
await this._page.mouse.apiWheel(progress, params.deltaX, params.deltaY);
}
async touchscreenTap(params: channels.PageTouchscreenTapParams, progress: Progress): Promise<void> {
await this._page.touchscreen.apiTap(progress, params.x, params.y);
}
async pdf(params: channels.PagePdfParams, progress: Progress): Promise<channels.PagePdfResult> {
if (!this._page.pdf)
throw new Error('PDF generation is only supported for Headless Chromium');
const buffer = await progress.race(this._page.pdf(params));
return { pdf: buffer };
}
async requests(params: channels.PageRequestsParams, progress: Progress): Promise<channels.PageRequestsResult> {
// Send all future requests to the client, so that it can reliably receive all of them.
// Otherwise, if subscription is added in a different task from this call (either before or after),
// there is a chance for a duplicate or a lost request.
this._subscriptions.add('request');
return { requests: this._page.networkRequests().map(request => RequestDispatcher.from(this.parentScope(), request)) };
}
async bringToFront(params: channels.PageBringToFrontParams, progress: Progress): Promise<void> {
await this._page.bringToFront(progress);
}
async pickLocator(params: channels.PagePickLocatorParams, progress: Progress): Promise<channels.PagePickLocatorResult> {
const recorder = await progress.race(Recorder.forContext(this._page.browserContext, { omitCallTracking: true, hideToolbar: true }));View on GitHub (pinned to c8fc3bf8d3)
Solutions
- Restrict page.pdf() calls to a chromium-only test project (configure projects in playwright.config to run the pdf spec only under chromium, headless).
- Guard the call: `if (browserName === 'chromium') await page.pdf(...)`.
- Ensure Chromium is launched headless (headless:true / 'new') — headed Chromium has no pdf backend either.
- For Firefox/WebKit, render to an image (page.screenshot fullPage) as an alternative output.
Example fix
// before
test('pdf', async ({ page }) => {
await page.pdf({ path: 'out.pdf' });
});
// after
test('pdf', async ({ page, browserName }) => {
test.skip(browserName !== 'chromium', 'PDF is Chromium-only');
await page.pdf({ path: 'out.pdf' });
}); Defensive patterns
Strategy: validation
Validate before calling
// Guard pdf() by browser type before calling.
if (browserName === 'chromium') {
await page.pdf({ path: 'out.pdf' });
} Type guard
// Narrow to a pdf-capable page.
function canPdf(browserName: string): boolean {
return browserName === 'chromium';
} Prevention
- Put pdf specs in a chromium-only test project.
- Keep Chromium headless for pdf runs — headed Chromium has no pdf backend.
- Use test.skip(browserName !== 'chromium') at the top of pdf specs.
When it happens
Trigger: Calling page.pdf() inside a test project configured for firefox or webkit; calling page.pdf() on Chromium launched with headless:false; running a shared page-interaction helper across all browser projects that unconditionally calls page.pdf().
Common situations: Cross-browser test suites with a single pdf spec file included in all projects; CI matrix that runs the same spec on chromium+firefox; switching a working Chromium suite to headed mode for debugging and forgetting pdf is called.
Related errors
- PDF creation is only working with Chromium
- CDP connections are only supported by Chromium
- Connecting to SELENIUM_REMOTE_URL is only supported by Chrom
AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12).
Data as JSON: /api/errors/cf6fab2972024cca.
Report an issue: GitHub.