jackwener/OpenCLI · error · CommandExecutionError
Could not find the ChatGPT model selector in the composer.
Error message
Could not find the ChatGPT model selector in the composer.
What it means
After ensuring the composer is visible, selectChatGPTModel evaluates a script to locate the model-selector button in the composer. If no matching element (by testid/aria-label/geometry) is found, menuButton.found stays false and the library throws CommandExecutionError. This guards against clicking at bogus coordinates.
Source
Thrown at clis/chatgpt/utils.js:650
let button = Array.from(document.querySelectorAll('form button')).find((node) =>
isVisible(node) && labels.some((label) => textMatchesLabel(node.textContent, label))
);
if (!button) {
button = menuButtonSelectors
.map((selector) => document.querySelector(selector))
.find((node) => node instanceof HTMLElement && isVisible(node));
}
if (!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 model menu button');
if (!menuButton.found) {
throw new CommandExecutionError('Could not find the ChatGPT model selector 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 escapeRegExp = (value) => String(value).replace(/[|\\\\{}()[\\]^$+*?.]/g, '\\\\$&');
const textMatchesLabel = (text, label) => {
const normalizedText = normalize(text);View on GitHub (pinned to 49907e53dc)
Solutions
- Retry after a short wait so the composer toolbar finishes rendering.
- Set OPENCLI_CHATGPT_MODEL_DEBUG=1 to inspect how far the flow got and what the page URL/state was.
- Open ChatGPT manually and confirm the model selector exists in your UI variant/locale; disable temporary-chat or special modes.
- Update the opencli package so its selector list matches the current ChatGPT DOM.
- If the API path applies to your target model, rely on setChatGPTModelConfig (API) rather than the picker fallback.
Example fix
// before await selectChatGPTModel(page, 'balanced'); // fails when UI not hydrated // after await page.wait(2); // let composer toolbar render await selectChatGPTModel(page, 'balanced');
Defensive patterns
Strategy: retry
Validate before calling
await ensureChatGPTComposer(page); await page.wait(1.5); // let the composer toolbar render before locating the selector button
Type guard
function menuButtonFound(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 selectChatGPTModel(page, model); }
catch (err) {
if (!(err instanceof CommandExecutionError) || !/model selector/.test(err.message)) throw err;
await page.wait(1.5);
}
}
throw new Error('model selector never appeared'); Prevention
- Wait for full page hydration before model selection.
- Avoid temporary-chat/canvas modes that hide the model picker.
- Track library updates for ChatGPT UI rollouts.
- Use a UI language covered by the selector labels (English or Chinese).
When it happens
Trigger: The model switcher button is absent from the composer DOM — typically a ChatGPT UI A/B variant or redesign, page not fully hydrated, locale rendering unexpected labels, the composer in a state where the selector is hidden (e.g. temporary chat, some compact layouts), or a CSP/environment blocking the evaluate script.
Common situations: ChatGPT frontend rollout changing data-testid of the model switcher; page checked too early before the composer toolbar renders; non-default ChatGPT modes (temporary chat, project canvases) that hide the model picker; layouts where the button rect is zero-sized.
Related errors
- ChatGPT composer is not available on the current page.
- Could not find the ChatGPT tools menu button 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/96708b4bcc780e2d.
Report an issue: GitHub.