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
- Use one of the supported actions: 'open', 'close', or 'run'
- Check the tool's parameter schema for the exact allowed action strings
- If you need element interaction, use the dedicated browser/tab sub-tools rather than an action on this tool
- 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
- Validate params.action against the schema before calling
- Only use 'open', 'close', 'run' — element ops live in tab sub-tools
- Keep tool-schema docs in sync with BrowserParams
- Constrain model tool-calling via strict JSON schema enums
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
- Browser selector must be a string; got ${kind}. tab.click/ty
- browser app.cdp_url must be the HTTP CDP discovery endpoint
- app.path must be absolute (got ${JSON.stringify(exe)}). Pass
- Drag ${role} must be a selector string or { x: number, y: nu
- tab.uploadFile() requires at least one file path
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/4f5506baa2d4c9b1.
Report an issue: GitHub.