{"record":{"id":"95ae053b3aa16a98","repo":"jackwener/OpenCLI","slug":"failed-to-click-model-option","errorCode":null,"errorMessage":"Failed to click model option","messagePattern":"Failed to click model option","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/kimi/ui.js","lineNumber":281,"sourceCode":"            const idx = exactIdx >= 0 ? exactIdx : partialMatches[0]?.index ?? -1;\n            if (idx < 0) {\n                try { await page.evaluate(`document.body.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }));`); } catch {}\n                throw new ArgumentError('set', `No model matched \"${wantSet}\". Available: ${opts.join(', ')}`);\n            }\n            const clickRes = await page.evaluate(`(() => {\n        ${IS_VISIBLE_JS}\n        const popovers = Array.from(document.querySelectorAll('[class*=\"popover\"i], [class*=\"dropdown\"i], [role=\"menu\"], [role=\"listbox\"]')).filter(isVisible);\n        const pop = popovers[popovers.length - 1];\n        if (!pop) return { ok: false };\n        const items = Array.from(pop.querySelectorAll('div, li, button, [role=\"option\"], [role=\"menuitem\"]'))\n          .filter(isVisible)\n          .filter((el) => { const t = (el.innerText || '').trim(); return t && t.length < 80 && (/K\\\\d|Kimi|Pro\\\\b|Auto|思考/.test(t)); });\n        const target = items[${idx}];\n        if (!target) return { ok: false };\n        target.click();\n        return { ok: true, clicked: (target.innerText || '').trim() };\n            })()`);\n            if (!clickRes?.ok) throw new CommandExecutionError('Failed to click model option', '');\n            await page.wait(0.5);\n            const verified = await page.evaluate(`(() => {\n      ${IS_VISIBLE_JS}\n      const svgs = Array.from(document.querySelectorAll('svg[name=\"Down_b\"]')).filter(isVisible);\n      for (const svg of svgs) {\n        let p = svg.parentElement;\n        for (let i = 0; i < 4 && p; i++) {\n          const spans = p.querySelectorAll('span');\n          for (const s of spans) {\n            const t = (s.textContent || '').trim();\n            if (/^K\\\\d|^Kimi |^Pro\\\\b|^Auto/.test(t)) return t;\n          }\n          p = p.parentElement;\n        }\n      }\n      return '';\n    })()`);\n            if (normalizeModel(verified) !== normalizeModel(clickRes.clicked)) {","sourceCodeStart":263,"sourceCodeEnd":299,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/kimi/ui.js#L263-L299","documentation":"After matching a model option by index, the command clicks it in the dropdown. If the targeted item element is missing (idx out of range of the re-queried item list) or the click result reports ok:false, it throws CommandExecutionError 'Failed to click model option'. The dropdown DOM changed between the options scan and the click.","triggerScenarios":"page.evaluate of the click script returns { ok:false } — the popover closed before the click, the option list re-rendered so items[idx] is undefined, or the item text filter (/K\\d|Kimi|Pro|Auto|思考/) excluded the target.","commonSituations":"Animation/transition closed the menu mid-flow; Kimi re-rendered options asynchronously; a slow page caused stale indices; option label doesn't match the text heuristic so items[] is shorter than opts[].","solutions":["Retry the model set command — a transient menu close is the usual cause.","Slow down automation: add a small wait after opening the dropdown before clicking.","Ensure nothing else (keyboard Escape, focus loss) dismisses the popover between scan and click.","Update the library if Kimi's option markup or labels changed."],"exampleFix":"// before\nconst clickRes = await page.evaluate(clickScript);\nif (!clickRes?.ok) throw new Error('Failed to click model option');\n// after\nawait page.wait(0.3); // let the menu settle\nconst clickRes = await page.evaluate(clickScript);\nif (!clickRes?.ok) { await reopenAndClick(); }","handlingStrategy":"retry","validationCode":"await page.waitForSelector('[role=\"listbox\"], [class*=\"popover\"i]'); // menu must be open & stable before clicking","typeGuard":"const clickedOk = (r) => !!r && r.ok === true && typeof r.clicked === 'string' && r.clicked.length > 0;","tryCatchPattern":"for (let i = 0; i < 3; i++) {\n  try { return await setKimiModel(page, want); }\n  catch (e) {\n    if (!/Failed to click model option/.test(e.message) || i === 2) throw e;\n    await page.wait(1);\n  }\n}","preventionTips":["Add small delays between opening the dropdown and clicking options.","Avoid keyboard/focus events that could close the popover mid-flow.","Run UI automation with stable (non-headless-race-prone) waits."],"tags":["dom","ui-automation","kimi"],"backgroundTag":"element-click-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}