n8n-io/n8n · warning · UnsupportedOperationError
Operation not supported: drag
Error message
Operation not supported: drag
What it means
Thrown as UnsupportedOperationError('drag', 'agent-browser') by the agent-browser adapter's drag() stub. The agent-browser CLI has no drag command, so the adapter explicitly rejects the operation rather than silently no-op'ing. UnsupportedOperationError extends McpBrowserError and carries a hint that the operation is not available for agent-browser sessions.
Source
Thrown at packages/@n8n/mcp-browser/src/adapters/agent-browser.ts:399
const resp = await this.run(['eval', script]);
if (!resp.success) throw new Error(resp.error ?? 'select failed');
return Array.isArray(resp.data) ? (resp.data as string[]) : values;
}
async hover(pageId: string, target: ElementTarget): Promise<void> {
await this.switchToTab(pageId);
await this.runAction(['hover', this.resolveTarget(target)]);
}
async press(pageId: string, keys: string): Promise<void> {
AgentBrowserAdapter.assertSafeArg(keys, 'key');
await this.switchToTab(pageId);
await this.runAction(['press', keys]);
}
async drag(_pageId: string, _from: ElementTarget, _to: ElementTarget): Promise<void> {
await Promise.resolve();
throw new UnsupportedOperationError('drag', this.name);
}
async scroll(pageId: string, target?: ElementTarget, options?: ScrollOptions): Promise<void> {
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,View on GitHub (pinned to 5ac6606e81)
Solutions
- Check adapter.name === 'agent-browser' before calling drag, and either skip the action or switch to the Playwright adapter.
- Emulate drag with a sequence of hover + mouse-down-equivalent clicks if the page supports it.
- Gate drag behind a capability check surfaced to the LLM so it doesn't emit unsupported actions.
Example fix
// before
await adapter.drag(pageId, from, to);
// after — guard by adapter capability
if (adapter.name === 'playwright') {
await adapter.drag(pageId, from, to);
} else {
// emulate, or surface 'unsupported' to the caller
} Defensive patterns
Strategy: validation
Validate before calling
function adapterSupportsDrag(name: string): boolean {
return name === 'playwright';
} Type guard
function supportsDrag(adapter: Adapter): boolean {
return adapter.name !== 'agent-browser';
} Prevention
- Check adapter.name before calling drag() — gate unsupported adapters.
- Surface capability metadata to the LLM so it doesn't emit unsupported actions.
- Prefer the Playwright adapter for sessions that need drag.
When it happens
Trigger: Calling adapter.drag(pageId, fromTarget, toTarget) on an AgentBrowserAdapter instance. The method awaits a resolved promise (to satisfy the async signature) then throws synchronously, so the rejection is immediate.
Common situations: A tool/orchestrator layer calls drag() generically across adapters without checking capability; a caller migrated from the Playwright adapter (which supports drag) to agent-browser; an LLM tool emitted a drag action against an agent-browser session.
Related errors
- Operation not supported: upload
- Operation not supported: dialog
- Operation not supported: pdf
- agent-browser failed
- Page not found: ${pageId}
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/7f6bde4c4a6dd677.
Report an issue: GitHub.