jackwener/OpenCLI · error · ArgumentError

Model "${wantSet}" is ambiguous: ${partialMatches.map(item =

Error message

Model "${wantSet}" is ambiguous: ${partialMatches.map(item => item.model).join(', ')}

What it means

When setting the Kimi model, the command normalizes the requested name and matches it against the options detected in the open model dropdown. If there is no exact normalized match but more than one option contains the needle as a substring, it closes the menu (Escape) and throws ArgumentError, because it cannot safely pick which model the user meant.

Source

Thrown at clis/kimi/ui.js:261

      const pop = popovers[popovers.length - 1];
      return Array.from(pop.querySelectorAll('div, li, button, [role="option"], [role="menuitem"]'))
        .filter(isVisible)
        .map((el) => (el.innerText || el.textContent || '').trim().replace(/\\s+/g, ' '))
        .filter((t) => t && t.length < 80 && (/K\\d|Kimi|Pro\\b|Auto|思考/.test(t)))
        .filter((t, i, arr) => arr.indexOf(t) === i)
        .slice(0, 20);
    })()`);

        if (wantSet) {
            const normalizeModel = (value) => String(value || '').toLowerCase().replace(/[^a-z0-9.\u4e00-\u9fa5]+/g, '');
            const needle = normalizeModel(wantSet);
            const exactIdx = opts.findIndex((t) => normalizeModel(t) === needle);
            const partialMatches = exactIdx >= 0 ? [] : opts
                .map((model, index) => ({ model, index }))
                .filter((item) => normalizeModel(item.model).includes(needle));
            if (exactIdx < 0 && partialMatches.length > 1) {
                try { await page.evaluate(`document.body.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }));`); } catch {}
                throw new ArgumentError('set', `Model "${wantSet}" is ambiguous: ${partialMatches.map(item => item.model).join(', ')}`);
            }
            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() };

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass the full, exact model name as shown in the dropdown (e.g. 'Kimi K2 Turbo' not 'k2').
  2. List available models first (the list command) and copy an exact option string.
  3. Include distinguishing characters in the query so only one option contains it.
  4. Handle ArgumentError in scripts by prompting for a more specific name.

Example fix

// before
await run('kimi', 'model', { set: 'k2' }); // ambiguous
// after
await run('kimi', 'model', { set: 'Kimi K2 Turbo' }); // exact
Defensive patterns

Strategy: validation

Validate before calling

const available = await run('kimi', 'model'); // list first
const exact = available.find(m => m.Model.toLowerCase() === want.toLowerCase());
if (!exact) throw new Error(`specify one of: ${available.map(m => m.Model).join(', ')}`);

Try / catch

try {
  await run('kimi', 'model', { set: want });
} catch (e) {
  if (/is ambiguous/.test(e.message)) {
    const candidates = e.message.split(': ')[1]?.split(', ') ?? [];
    throw new Error(`Refine the model name; candidates: ${candidates.join(' | ')}`);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling the kimi model set command with a partial name matching multiple entries, e.g. set='k2' when options include 'K2', 'K2 turbo', 'K2-thinking' (normalized substring matches >1 and no exact match).

Common situations: Using abbreviated model names in scripts; Kimi added new variants sharing a prefix; case/spacing differences defeat exact match so several partials remain.

Related errors


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