jackwener/OpenCLI · error · CommandExecutionError

Failed to click model option

Error message

Failed to click model option

What it means

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.

Source

Thrown at clis/kimi/ui.js:281

            const idx = exactIdx >= 0 ? exactIdx : partialMatches[0]?.index ?? -1;
            if (idx < 0) {
                try { await page.evaluate(`document.body.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }));`); } catch {}
                throw new ArgumentError('set', `No model matched "${wantSet}". Available: ${opts.join(', ')}`);
            }
            const clickRes = await page.evaluate(`(() => {
        ${IS_VISIBLE_JS}
        const popovers = Array.from(document.querySelectorAll('[class*="popover"i], [class*="dropdown"i], [role="menu"], [role="listbox"]')).filter(isVisible);
        const pop = popovers[popovers.length - 1];
        if (!pop) return { ok: false };
        const items = Array.from(pop.querySelectorAll('div, li, button, [role="option"], [role="menuitem"]'))
          .filter(isVisible)
          .filter((el) => { const t = (el.innerText || '').trim(); return t && t.length < 80 && (/K\\d|Kimi|Pro\\b|Auto|思考/.test(t)); });
        const target = items[${idx}];
        if (!target) return { ok: false };
        target.click();
        return { ok: true, clicked: (target.innerText || '').trim() };
            })()`);
            if (!clickRes?.ok) throw new CommandExecutionError('Failed to click model option', '');
            await page.wait(0.5);
            const verified = await page.evaluate(`(() => {
      ${IS_VISIBLE_JS}
      const svgs = Array.from(document.querySelectorAll('svg[name="Down_b"]')).filter(isVisible);
      for (const svg of svgs) {
        let p = svg.parentElement;
        for (let i = 0; i < 4 && p; i++) {
          const spans = p.querySelectorAll('span');
          for (const s of spans) {
            const t = (s.textContent || '').trim();
            if (/^K\\d|^Kimi |^Pro\\b|^Auto/.test(t)) return t;
          }
          p = p.parentElement;
        }
      }
      return '';
    })()`);
            if (normalizeModel(verified) !== normalizeModel(clickRes.clicked)) {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Retry the model set command — a transient menu close is the usual cause.
  2. Slow down automation: add a small wait after opening the dropdown before clicking.
  3. Ensure nothing else (keyboard Escape, focus loss) dismisses the popover between scan and click.
  4. Update the library if Kimi's option markup or labels changed.

Example fix

// before
const clickRes = await page.evaluate(clickScript);
if (!clickRes?.ok) throw new Error('Failed to click model option');
// after
await page.wait(0.3); // let the menu settle
const clickRes = await page.evaluate(clickScript);
if (!clickRes?.ok) { await reopenAndClick(); }
Defensive patterns

Strategy: retry

Validate before calling

await page.waitForSelector('[role="listbox"], [class*="popover"i]'); // menu must be open & stable before clicking

Type guard

const clickedOk = (r) => !!r && r.ok === true && typeof r.clicked === 'string' && r.clicked.length > 0;

Try / catch

for (let i = 0; i < 3; i++) {
  try { return await setKimiModel(page, want); }
  catch (e) {
    if (!/Failed to click model option/.test(e.message) || i === 2) throw e;
    await page.wait(1);
  }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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[].

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/95ae053b3aa16a98. Report an issue: GitHub.