jackwener/OpenCLI · error · CommandExecutionError

Model name "${rawName}" is ambiguous.

Error message

Model name "${rawName}" is ambiguous.

What it means

When resolving the requested model name against the labels scraped from the Codex model menu, `findUniqueModelOption` first filters for exact normalized matches. This CommandExecutionError is thrown when more than one label exactly matches the requested name after normalization (lowercased, 'gpt' prefix stripped, whitespace collapsed), because the library cannot tell which menu item to click. The error detail lists all matching labels.

Source

Thrown at clis/codex/model.js:56

}

function extractModelVersion(value) {
    const match = value.match(/(?:^|\s)(\d+(?:\.\d+)?)(?=\s|$)/);
    return match?.[1] || '';
}

export function findUniqueModelOption(labels, rawName) {
    const name = normalizeModelText(rawName);
    if (!name) {
        throw new ArgumentError('model name cannot be empty');
    }
    const normalized = labels.map((label) => ({ label, normalized: normalizeModelText(label) }));
    const exact = normalized.filter(item => item.normalized === name);
    if (exact.length === 1) {
        return exact[0].label;
    }
    if (exact.length > 1) {
        throw new CommandExecutionError(`Model name "${rawName}" is ambiguous.`, `Matches: ${exact.map(item => item.label).join(', ')}`);
    }
    const partial = normalized.filter(item => item.normalized.includes(name));
    if (partial.length === 1) {
        return partial[0].label;
    }
    if (partial.length > 1) {
        throw new CommandExecutionError(`Model name "${rawName}" is ambiguous.`, `Matches: ${partial.map(item => item.label).join(', ')}`);
    }
    return null;
}

export function modelSelectionVerified(current, chosen) {
    const active = normalizeModelText(current);
    const selected = normalizeModelText(chosen);
    if (!active || !selected) {
        return false;
    }
    if (active === selected) {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Use a more specific name that uniquely identifies one menu item (check the detail line's Matches list).
  2. Run `opencli codex model --list` to see exactly which labels are available and pick a unique substring.
  3. Update opencli if a new Codex version added unfiltered menu items causing false collisions.

Example fix

// before
opencli codex model "5"            // matches GPT-5.5 and GPT-5.4
// after
opencli codex model "5.5"          # unique exact match
# or inspect first:
opencli codex model --list
Defensive patterns

Strategy: validation

Validate before calling

const listed = await run('opencli codex model --list');
const labels = parseLabels(listed);
const norm = s => s.toLowerCase().replace(/\bgpt[-\s]*/g, '').replace(/\s+/g, ' ').trim();
if (labels.filter(l => norm(l) === norm(wanted)).length > 1) {
  throw new Error(`Ambiguous model "${wanted}"; pick from: ${labels.join(', ')}`);
}

Type guard

function uniqueMatch(labels, name) {
  const n = s => s.toLowerCase().replace(/\bgpt[-\s]*/g,'').replace(/\s+/g,' ').trim();
  const m = labels.filter(l => n(l) === n(name));
  return m.length === 1 ? m[0] : null;
}

Try / catch

try {
  await switchModel(name);
} catch (err) {
  if (err instanceof CommandExecutionError && /is ambiguous/.test(err.message)) {
    // parse Matches: list from err.detail and re-invoke with the full exact label
  } else throw err;
}

Prevention

When it happens

Trigger: Running `opencli codex model <name>` when two or more menu items normalize to the same text — e.g., the menu lists both a model variant and a reasoning option whose normalized labels collide, or duplicate entries appear in the opened menu (chat-action items not filtered out).

Common situations: Menus polluted with unrelated items (the code filters known chat-action labels, but a Codex update can introduce new ones); asking for a name that matches both a model and a reasoning level (e.g. 'pro'); duplicate model entries rendered by a newer Codex build.

Related errors


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