n8n-io/n8n · warning · UnsupportedOperationError

Operation not supported: pdf

Error message

Operation not supported: pdf

What it means

Thrown as UnsupportedOperationError('pdf', 'agent-browser') by the agent-browser adapter's pdf() stub. The agent-browser CLI cannot render PDFs, so the adapter explicitly rejects the operation. UnsupportedOperationError extends McpBrowserError. The Playwright adapter supports pdf rendering; agent-browser does not.

Source

Thrown at packages/@n8n/mcp-browser/src/adapters/agent-browser.ts:526

	getConsoleSummary(_pageId: string): { errors: number; warnings: number } {
		return { errors: 0, warnings: 0 };
	}

	getModalStates(_pageId: string): ModalState[] {
		return [];
	}

	async getNetwork(_pageId: string, _filter?: string, _clear?: boolean): Promise<NetworkEntry[]> {
		await Promise.resolve();
		return [];
	}

	async pdf(
		_pageId: string,
		_options?: { format?: string; landscape?: boolean },
	): Promise<{ data: string; pages: number }> {
		await Promise.resolve();
		throw new UnsupportedOperationError('pdf', this.name);
	}

	// =========================================================================
	// Wait
	// =========================================================================

	async wait(pageId: string, options: WaitOptions): Promise<number> {
		await this.switchToTab(pageId);
		const timeout = options.timeoutMs ?? 30_000;
		const start = Date.now();
		if (options.selector) {
			AgentBrowserAdapter.assertSafeArg(options.selector, 'selector');
			await this.run(['wait', options.selector], timeout + 5_000);
		} else if (options.text) {
			await this.run(['wait', 'text=' + options.text], timeout + 5_000);
		} else if (options.timeoutMs) {
			await this.run(['wait', String(options.timeoutMs)], timeout + 5_000);
		} else {

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Switch to the Playwright adapter when PDF generation is required.
  2. Gate pdf behind adapter.name === 'playwright' before calling.
  3. For agent-browser, capture a screenshot() instead if a visual snapshot is acceptable.

Example fix

// before
const pdf = await adapter.pdf(pageId);

// after — fall back to screenshot on agent-browser
const image = adapter.name === 'playwright'
  ? await adapter.pdf(pageId)
  : await adapter.screenshot(pageId);
Defensive patterns

Strategy: validation

Validate before calling

function adapterSupportsPdf(name: string): boolean {
  return name === 'playwright';
}

Type guard

function supportsPdf(adapter: Adapter): boolean {
  return adapter.name !== 'agent-browser';
}

Prevention

When it happens

Trigger: Calling adapter.pdf(pageId, options?) on an AgentBrowserAdapter instance. The method awaits a resolved promise then throws synchronously.

Common situations: A tool layer calls pdf() generically across adapters; migrating from Playwright to agent-browser; an LLM emitted a pdf-generation tool call against an agent-browser session.

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/4f7bd208b997c3c0. Report an issue: GitHub.