jackwener/OpenCLI · error · ArgumentError

Unknown ChatGPT tool "${tool}"

Error message

Unknown ChatGPT tool "${tool}"

What it means

requireKnownChatGPTTool validates the requested tool name against CHATGPT_TOOL_OPTIONS (only 'deep-research' and 'web-search') and throws ArgumentError otherwise. Tools are ChatGPT composer capabilities the CLI can switch on via the UI; anything else is rejected up front with the list of valid choices.

Source

Thrown at clis/chatgpt/utils.js:395

function requireKnownChatGPTModel(model) {
    const key = String(model ?? '').trim().toLowerCase();
    const targetKey = CHATGPT_MODEL_ALIASES[key] || key;
    const option = CHATGPT_MODEL_TARGETS[targetKey];
    if (!option) {
        throw new ArgumentError(
            `Unknown ChatGPT model "${model}"`,
            `Choose one of: ${CHATGPT_MODEL_CHOICES.join(', ')}`,
        );
    }
    return { key: targetKey, alias: key !== targetKey ? key : null, ...option };
}

function requireKnownChatGPTTool(tool) {
    const key = String(tool ?? '').trim().toLowerCase();
    const option = CHATGPT_TOOL_OPTIONS[key];
    if (!option) {
        throw new ArgumentError(
            `Unknown ChatGPT tool "${tool}"`,
            `Choose one of: ${CHATGPT_TOOL_CHOICES.join(', ')}`,
        );
    }
    return { key, ...option };
}

export async function getCurrentChatGPTModel(page) {
    return 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 normalize = (value) => String(value || '').replace(/\\s+/g, ' ').trim();
        const escapeRegExp = (value) => String(value).replace(/[|\\\\{}()[\\]^$+*?.]/g, '\\\\$&');

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Use exactly 'deep-research' or 'web-search' as the tool value.
  2. Check the error's suggestion text, which lists CHATGPT_TOOL_CHOICES.
  3. Hyphenate multi-word tools ('web search' -> 'web-search'); lookup is lowercased but not whitespace-normalized.
  4. Update the library if ChatGPT added new selectable tools you need.

Example fix

// before
await chatgpt.tool({ tool: 'search' }); // ArgumentError
// after
await chatgpt.tool({ tool: 'web-search' });
Defensive patterns

Strategy: validation

Validate before calling

import { CHATGPT_TOOL_CHOICES } from '@jackwener/opencli/chatgpt/utils';
if (!CHATGPT_TOOL_CHOICES.includes(String(tool ?? '').trim().toLowerCase())) {
  throw new Error(`tool must be one of: ${CHATGPT_TOOL_CHOICES.join(', ')}`);
}

Type guard

function isKnownChatGPTTool(tool) {
  return tool === 'deep-research' || tool === 'web-search';
}

Try / catch

try {
  await selectChatGPTTool(page, tool);
} catch (err) {
  if (err instanceof ArgumentError && /Unknown ChatGPT tool/.test(err.message)) {
    console.error(err.suggestion ?? err.message);
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling a tool-selection path (requireKnownChatGPTTool via target) with names like 'search', 'code-interpreter', 'canvas', 'image-gen', or a localized variant not in the option map; the map only accepts the exact keys deep-research and web-search.

Common situations: Config scripts referencing ChatGPT features by their UI wording rather than the CLI's keys; expecting every ChatGPT GPT/tool to be selectable; older configs using names like 'browse' or 'research' alone.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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