can1357/oh-my-pi · error · ToolError

Unsupported action: ${(params as BrowserParams).action}

Error message

Unsupported action: ${(params as BrowserParams).action}

What it means

The browser tool's execute() dispatches on params.action ('open'|'close'|'run'). Any other action value falls through the switch default and throws this ToolError naming the unsupported action. It is an input-validation error protecting the internal dispatch table.

Source

Thrown at packages/coding-agent/src/tools/browser.ts:246

		_onUpdate?: AgentToolUpdateCallback<BrowserToolDetails>,
		_ctx?: AgentToolContext,
	): Promise<AgentToolResult<BrowserToolDetails>> {
		try {
			throwIfAborted(signal);
			const timeoutSeconds = clampTimeout("browser", params.timeout, this.session.settings.get("tools.maxTimeout"));
			const timeoutMs = timeoutSeconds * 1000;
			const name = params.name ?? DEFAULT_TAB_NAME;
			const details: BrowserToolDetails = { action: params.action, name };

			switch (params.action) {
				case "open":
					return await this.#open(name, params, details, timeoutMs, signal);
				case "close":
					return await this.#close(name, params, details, timeoutMs, signal);
				case "run":
					return await this.#run(name, params, details, timeoutMs, signal);
				default:
					throw new ToolError(`Unsupported action: ${(params as BrowserParams).action}`);
			}
		} catch (error) {
			if (error instanceof ToolAbortError) throw error;
			if (error instanceof Error && error.name === "AbortError") {
				throw new ToolAbortError();
			}
			throw error;
		}
	}

	async #open(
		name: string,
		params: BrowserParams,
		details: BrowserToolDetails,
		timeoutMs: number,
		signal?: AbortSignal,
	): Promise<AgentToolResult<BrowserToolDetails>> {
		const kind = resolveBrowserKind(params, this.session);

View on GitHub (pinned to 9690622007)

Solutions

  1. Use one of the supported actions: 'open', 'close', or 'run'
  2. Check the tool's parameter schema for the exact allowed action strings
  3. If you need element interaction, use the dedicated browser/tab sub-tools rather than an action on this tool
  4. Update the caller/code generation to match the current BrowserParams schema

Example fix

// before
await browser.run({ action: 'navigate', url })
// after
await browser.run({ action: 'open', url })
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED = new Set(['open', 'close', 'run']);
if (!SUPPORTED.has(params.action)) {
	throw new Error(`action must be one of ${[...SUPPORTED].join(', ')}`);
}

Type guard

function isBrowserAction(a: unknown): a is 'open' | 'close' | 'run' {
	return a === 'open' || a === 'close' || a === 'run';
}

Try / catch

try {
	await browserTool.execute(params, ...);
} catch (err) {
	if (err instanceof ToolError && err.message.startsWith('Unsupported action')) {
		// fix params.action to 'open' | 'close' | 'run' and retry
	} else throw err;
}

Prevention

When it happens

Trigger: Passing params.action with a typo or an action this tool version does not support ('goto', 'click', 'eval', etc. instead of open/close/run); model-generated tool arguments inventing an action name; older/newer tool schema mismatch between caller and implementation.

Common situations: LLM hallucinating an action name in tool args; hand-written RPC/SDK code calling browser with an unlisted action; stale docs listing a removed action.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/4f5506baa2d4c9b1. Report an issue: GitHub.