jackwener/OpenCLI · error · CommandExecutionError
ChatGPT model did not switch to ${target.label}.
Error message
ChatGPT model did not switch to ${target.label}. What it means
After clicking the option, the library verifies via getCurrentChatGPTModel (and, for intelligence-ordered models, the checked item's order in the reopened menu) that the active model actually changed to target. If the verification fails it closes the menu and throws CommandExecutionError. This is a post-condition check, not a click failure.
Source
Thrown at clis/chatgpt/utils.js:761
return rect.width > 0 && rect.height > 0;
};
const target = ${JSON.stringify(target)};
const intelligenceContent = document.querySelector('[data-testid="composer-intelligence-picker-content"]');
const options = intelligenceContent
? Array.from(intelligenceContent.querySelectorAll('[role="menuitemradio"]')).filter(isVisible)
: [];
const checkedIndex = options.findIndex((node) => node.getAttribute('aria-checked') === 'true');
return {
recognized: options.length === 5 && Number.isInteger(target.intelligenceOrder),
checkedIndex,
};
})()`)), 'chatgpt model checked intelligence option');
if (checked.recognized && checked.checkedIndex === target.intelligenceOrder) {
await page.nativeClick(Number(menuButton.x), Number(menuButton.y));
return { Status: 'Success', Model: target.label };
}
await page.nativeClick(Number(menuButton.x), Number(menuButton.y));
throw new CommandExecutionError(`ChatGPT model did not switch to ${target.label}.`);
}
return { Status: 'Success', Model: target.label };
}
export async function getCurrentChatGPTTool(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 compact = (value) => normalize(value).toLowerCase().replace(/[^\\p{L}\\p{N}]+/gu, '');
const matchesLabel = (value, labels) => {
const normalized = normalize(value).toLowerCase();
const compacted = compact(value);View on GitHub (pinned to 49907e53dc)
Solutions
- Re-read the model with getCurrentChatGPTModel after a short wait — the switch may just settle late.
- Retry the selection once; transient races are common on slow sessions.
- Verify the account entitlement for the requested tier so ChatGPT doesn't revert it.
- Set OPENCLI_CHATGPT_MODEL_DEBUG=1 to see the before/after model reads and the checked index.
Example fix
// before
await selectChatGPTModel(page, 'advanced'); // may throw on slow settle
// after
try {
await selectChatGPTModel(page, 'advanced');
} catch (err) {
if (err.message.includes('did not switch to')) {
await page.wait(2);
const cur = await getCurrentChatGPTModel(page);
if (cur.model === 'advanced') return cur; // switched after all
}
throw err;
} Defensive patterns
Strategy: retry
Validate before calling
const before = await getCurrentChatGPTModel(page); if (before.model === targetKey) return; // already active, nothing to do
Type guard
function switchedTo(current, targetKey) {
return current != null && current.model === targetKey;
} Try / catch
try {
await selectChatGPTModel(page, model);
} catch (err) {
if (err instanceof CommandExecutionError && /did not switch to/.test(err.message)) {
await page.wait(2);
const after = await getCurrentChatGPTModel(page); // re-read after settling
if (after.model === expectedKey) return after; // eventual consistency
throw err;
}
throw err;
} Prevention
- Add a settle delay after the click before asserting model state.
- Verify account entitlement so ChatGPT doesn't silently revert the preference.
- Prefer the API path (setChatGPTModelConfig) when the target model supports it.
- Re-read current model instead of trusting a single immediate read.
When it happens
Trigger: The click landed but the model didn't switch: the click hit a disabled/partially rendered option, ChatGPT reverted the preference server-side (entitlement or session issue), the current-model read raced ahead of the UI update, or for intelligenceOrder targets the checked index didn't match target.intelligenceOrder.
Common situations: Paid tiers silently unavailable so ChatGPT reverts the preference; click landing during a menu re-render; verification racing the UI update; for intelligence-ordered models the checked index not matching target.intelligenceOrder.
Related errors
- Failed to export generated ChatGPT image assets
- Failed to upload file to ChatGPT project knowledge: ${err in
- Failed to upload file to ChatGPT project knowledge
- chatgpt project-list
- chatgpt read
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/3523deebd1dbddf6.
Report an issue: GitHub.