jackwener/OpenCLI · error · CommandExecutionError

ChatGPT tool selection requires native browser click support

Error message

ChatGPT tool selection requires native browser click support.

What it means

selectChatGPTTool drives the tools ("+" / actions) menu with real mouse input, so it requires page.nativeClick to exist. If the page object lacks that method it throws CommandExecutionError immediately, before navigating or checking login, mirroring the model-selection capability check.

Source

Thrown at clis/chatgpt/utils.js:825

            ? [
                node.textContent,
                node.getAttribute('aria-label'),
                node.getAttribute('title'),
                node.getAttribute('data-testid'),
            ]
            : [];
        const entry = Object.entries(labels).find(([, value]) => haystacks.some((candidate) => matchesLabel(candidate, value.labels)));
        return {
            tool: entry?.[0] ?? null,
            label: entry?.[1]?.label ?? null,
        };
    })()`)), 'chatgpt current tool');
}

export async function selectChatGPTTool(page, tool) {
    const target = requireKnownChatGPTTool(tool);
    if (typeof page.nativeClick !== 'function') {
        throw new CommandExecutionError('ChatGPT tool selection requires native browser click support.');
    }
    await ensureOnChatGPT(page);
    await ensureChatGPTComposer(page, 'ChatGPT tool selection requires a logged-in ChatGPT session with a visible composer.');

    const before = await getCurrentChatGPTTool(page);
    if (before.tool === target.key) {
        return { Status: 'Already selected', Tool: target.label };
    }

    const menuButton = requireObjectEvaluateResult(unwrapEvaluateResult(await page.evaluate(`(() => {
        const isVisible = (el) => {
            if (!(el instanceof HTMLElement)) return false;
            const style = window.getComputedStyle(el);
            if (style.display === 'none' || style.visibility === 'hidden') return false;
            const rect = el.getBoundingClientRect();
            return rect.width > 0 && rect.height > 0;
        };
        const button = document.querySelector('button[data-testid="composer-plus-btn"]');

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Use the OpenCLI CDP page object that implements nativeClick.
  2. Update/fix the browser driver so mouse input (CDP Input domain) works.
  3. Extend test page stubs with a nativeClick(x, y) implementation.
  4. Toggle the tool manually in the ChatGPT UI if native clicks are impossible in your environment.

Example fix

// before
const page = fakePage(); // no nativeClick
await selectChatGPTTool(page, 'web-search');
// after
const page = await opencli.browser.open('https://chatgpt.com');
await selectChatGPTTool(page, 'web-search');
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof page.nativeClick !== 'function') {
  throw new Error('Tool selection needs a CDP page with nativeClick support.');
}

Type guard

function supportsToolSelection(page) {
  return page != null && typeof page.nativeClick === 'function' && typeof page.evaluate === 'function';
}

Try / catch

try {
  await selectChatGPTTool(page, tool);
} catch (err) {
  if (err instanceof CommandExecutionError && /native browser click support/.test(err.message)) {
    page = await opencli.browser.open('https://chatgpt.com');
    return selectChatGPTTool(page, tool);
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling selectChatGPTTool with a page from a driver that doesn't implement nativeClick — minimal test fakes, alternate automation libraries exposing only evaluate(), or browser environments with CDP input injection disabled.

Common situations: Swapping drivers or downgrading the browser adapter; injecting a mock page in CI without nativeClick; remote/embedded browsers that strip input domains.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/e24be739738ed7f0. Report an issue: GitHub.