n8n-io/n8n · warning · UnsupportedOperationError

Operation not supported: upload

Error message

Operation not supported: upload

What it means

Thrown as UnsupportedOperationError('upload', 'agent-browser') by the agent-browser adapter's upload() stub. The agent-browser CLI has no file-upload command, so the adapter explicitly rejects the operation. UnsupportedOperationError extends McpBrowserError with a hint that the operation is unavailable for agent-browser sessions. The Playwright adapter supports upload; agent-browser does not.

Source

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

		await this.switchToTab(pageId);
		if (target) {
			await this.runAction(['scrollintoview', this.resolveTarget(target)]);
		} else {
			await this.runAction([
				'scroll',
				options?.direction ?? 'down',
				String(options?.amount ?? 300),
			]);
		}
	}

	async upload(
		_pageId: string,
		_target: ElementTarget | undefined,
		_files: string[],
	): Promise<void> {
		await Promise.resolve();
		throw new UnsupportedOperationError('upload', this.name);
	}

	async dialog(_pageId: string, _action: 'accept' | 'dismiss', _text?: string): Promise<string> {
		await Promise.resolve();
		throw new UnsupportedOperationError('dialog', this.name);
	}

	// =========================================================================
	// Inspection
	// =========================================================================

	async snapshot(
		pageId: string,
		_target?: ElementTarget,
		interactive = true,
	): Promise<SnapshotResult> {
		await this.switchToTab(pageId);
		const args = interactive ? ['snapshot', '-i'] : ['snapshot'];

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Switch to the Playwright adapter for sessions that need file upload.
  2. Gate upload behind adapter.name === 'playwright' before calling.
  3. Surface upload as an unsupported capability to the LLM/tool layer so it doesn't emit the call.

Example fix

// before
await adapter.upload(pageId, target, ['/tmp/file.csv']);

// after — capability gate
if (adapter.name === 'playwright') {
  await adapter.upload(pageId, target, ['/tmp/file.csv']);
} else {
  throw new Error('File upload is not supported in this browser session.');
}
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

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

Prevention

When it happens

Trigger: Calling adapter.upload(pageId, target, files) on an AgentBrowserAdapter instance. The method awaits a resolved promise then throws synchronously.

Common situations: A tool layer calls upload() generically without checking the adapter capability; migrating from Playwright adapter to agent-browser; an LLM emitted an upload 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/2a6e4c61a607bded. Report an issue: GitHub.