{"record":{"id":"3523deebd1dbddf6","repo":"jackwener/OpenCLI","slug":"chatgpt-model-did-not-switch-to-target-label","errorCode":null,"errorMessage":"ChatGPT model did not switch to ${target.label}.","messagePattern":"ChatGPT model did not switch to (.+?)\\.","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/chatgpt/utils.js","lineNumber":761,"sourceCode":"                return rect.width > 0 && rect.height > 0;\n            };\n            const target = ${JSON.stringify(target)};\n            const intelligenceContent = document.querySelector('[data-testid=\"composer-intelligence-picker-content\"]');\n            const options = intelligenceContent\n                ? Array.from(intelligenceContent.querySelectorAll('[role=\"menuitemradio\"]')).filter(isVisible)\n                : [];\n            const checkedIndex = options.findIndex((node) => node.getAttribute('aria-checked') === 'true');\n            return {\n                recognized: options.length === 5 && Number.isInteger(target.intelligenceOrder),\n                checkedIndex,\n            };\n        })()`)), 'chatgpt model checked intelligence option');\n        if (checked.recognized && checked.checkedIndex === target.intelligenceOrder) {\n            await page.nativeClick(Number(menuButton.x), Number(menuButton.y));\n            return { Status: 'Success', Model: target.label };\n        }\n        await page.nativeClick(Number(menuButton.x), Number(menuButton.y));\n        throw new CommandExecutionError(`ChatGPT model did not switch to ${target.label}.`);\n    }\n    return { Status: 'Success', Model: target.label };\n}\n\nexport async function getCurrentChatGPTTool(page) {\n    return requireObjectEvaluateResult(unwrapEvaluateResult(await page.evaluate(`(() => {\n        const isVisible = (el) => {\n            if (!(el instanceof HTMLElement)) return false;\n            const style = window.getComputedStyle(el);\n            if (style.display === 'none' || style.visibility === 'hidden') return false;\n            const rect = el.getBoundingClientRect();\n            return rect.width > 0 && rect.height > 0;\n        };\n            const normalize = (value) => String(value || '').replace(/\\\\s+/g, ' ').trim();\n            const compact = (value) => normalize(value).toLowerCase().replace(/[^\\\\p{L}\\\\p{N}]+/gu, '');\n            const matchesLabel = (value, labels) => {\n                const normalized = normalize(value).toLowerCase();\n                const compacted = compact(value);","sourceCodeStart":743,"sourceCodeEnd":779,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/chatgpt/utils.js#L743-L779","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nawait selectChatGPTModel(page, 'advanced'); // may throw on slow settle\n// after\ntry {\n  await selectChatGPTModel(page, 'advanced');\n} catch (err) {\n  if (err.message.includes('did not switch to')) {\n    await page.wait(2);\n    const cur = await getCurrentChatGPTModel(page);\n    if (cur.model === 'advanced') return cur; // switched after all\n  }\n  throw err;\n}","handlingStrategy":"retry","validationCode":"const before = await getCurrentChatGPTModel(page);\nif (before.model === targetKey) return; // already active, nothing to do","typeGuard":"function switchedTo(current, targetKey) {\n  return current != null && current.model === targetKey;\n}","tryCatchPattern":"try {\n  await selectChatGPTModel(page, model);\n} catch (err) {\n  if (err instanceof CommandExecutionError && /did not switch to/.test(err.message)) {\n    await page.wait(2);\n    const after = await getCurrentChatGPTModel(page); // re-read after settling\n    if (after.model === expectedKey) return after; // eventual consistency\n    throw err;\n  }\n  throw err;\n}","preventionTips":["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."],"tags":["browser-automation","chatgpt","state-verification"],"backgroundTag":"ui-action-verification-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}