jackwener/OpenCLI · error · CommandExecutionError
Could not find the ChatGPT tools menu button in the composer
Error message
Could not find the ChatGPT tools menu button in the composer.
What it means
selectChatGPTTool evaluates a script to find the tools-menu button in the composer; if no element matches, menuButton.found is false and it throws CommandExecutionError. Like the model-selector case, this exists to avoid clicking invalid coordinates when the expected control is missing from the DOM.
Source
Thrown at clis/chatgpt/utils.js:854
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"]');
if (!(button instanceof HTMLElement) || !isVisible(button)) return { found: false };
button.scrollIntoView({ block: 'center', inline: 'center' });
const rect = button.getBoundingClientRect();
return {
found: true,
x: Math.round(rect.left + rect.width / 2),
y: Math.round(rect.top + rect.height / 2),
};
})()`)), 'chatgpt tools menu button');
if (!menuButton.found) {
throw new CommandExecutionError('Could not find the ChatGPT tools menu button in the composer.');
}
await page.nativeClick(Number(menuButton.x), Number(menuButton.y));
await page.wait(0.5);
let optionCenter = null;
for (let attempt = 0; attempt < 10; attempt += 1) {
optionCenter = 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 compact = (value) => normalize(value).toLowerCase().replace(/[^\\p{L}\\p{N}]+/gu, '');
const labels = ${JSON.stringify(target.labels)};
const optionSelector = '[role="menuitemradio"], [role="menuitem"], [role="option"], button, div[tabindex="0"]';View on GitHub (pinned to 49907e53dc)
Solutions
- Retry after a brief wait so the composer toolbar finishes rendering.
- Open ChatGPT manually and confirm the tools ("+") button exists in your UI variant/locale; exit special modes like canvas/voice.
- Set OPENCLI_CHATGPT_MODEL_DEBUG=1 to trace the failing step.
- Update the opencli package so its selectors match the current ChatGPT DOM.
Example fix
// before await selectChatGPTTool(page, 'deep-research'); // tools button not yet rendered // after await page.wait(2); await selectChatGPTTool(page, 'deep-research');
Defensive patterns
Strategy: retry
Validate before calling
await ensureChatGPTComposer(page); await page.wait(1.5); // let composer toolbar (with the "+" tools button) render
Type guard
function toolsButtonFound(res) {
return res != null && res.found === true && Number.isFinite(Number(res.x)) && Number.isFinite(Number(res.y));
} Try / catch
for (let i = 0; i < 3; i++) {
try { return await selectChatGPTTool(page, tool); }
catch (err) {
if (!(err instanceof CommandExecutionError) || !/tools menu button/.test(err.message)) throw err;
await page.wait(1.5);
}
}
throw new Error('tools menu button never appeared'); Prevention
- Wait for composer hydration before tool selection.
- Exit canvas/voice/temporary-chat modes that hide the tools button.
- Keep the UI language within the supported label set.
- Track library updates for ChatGPT toolbar DOM changes.
When it happens
Trigger: The tools menu button ("+" actions button) is not present in the composer — ChatGPT UI variant/redesign, page not hydrated yet, locale/labels mismatch, special composer states (canvas, voice mode, some workspaces) hiding the tools button, or the evaluate script being blocked/returning unexpected shapes.
Common situations: New ChatGPT layouts that relocate or rename the tools button; automation running before the composer toolbar renders; UI language not covered by the labels list; temporary chat or feature-flagged variants where the tools menu is absent.
Related errors
- ChatGPT composer is not available on the current page.
- Could not find the ChatGPT model selector in the composer.
- Could not click the ChatGPT ${target.label} model option.
- SignOut svg not found
- upgrade click failed
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/3d10cfb0c4499d99.
Report an issue: GitHub.