jackwener/OpenCLI · error · CommandExecutionError

Picker option "${rawLabel}" is ambiguous.

Error message

Picker option "${rawLabel}" is ambiguous.

What it means

When matching --pick against picker options, the library first looks for an exact (case/whitespace-insensitive) title match. If more than one option's normalized title equals the wanted label, it throws CommandExecutionError with the list of matching titles rather than guessing.

Source

Thrown at clis/codex/send.js:24

const PICKER_ITEM_SELECTOR = '[data-list-navigation-item="true"]';

export function findUniquePickerOption(options, rawLabel) {
    const wanted = String(rawLabel ?? '').replace(/\s+/g, ' ').trim().toLowerCase();
    if (!wanted) {
        throw new ArgumentError('--pick label cannot be empty');
    }
    const normalized = options.map((option, index) => ({
        index,
        title: String(option.title ?? ''),
        normalizedTitle: String(option.title ?? '').replace(/\s+/g, ' ').trim().toLowerCase(),
        normalizedText: String(option.text ?? option.title ?? '').replace(/\s+/g, ' ').trim().toLowerCase(),
    }));
    const exact = normalized.filter(item => item.normalizedTitle === wanted);
    if (exact.length === 1) {
        return exact[0];
    }
    if (exact.length > 1) {
        throw new CommandExecutionError(`Picker option "${rawLabel}" is ambiguous.`, `Matches: ${exact.map(item => item.title).join(', ')}`);
    }
    const partial = normalized.filter(item => item.normalizedText.includes(wanted));
    if (partial.length === 1) {
        return partial[0];
    }
    if (partial.length > 1) {
        throw new CommandExecutionError(`Picker option "${rawLabel}" is ambiguous.`, `Matches: ${partial.map(item => item.title).join(', ')}`);
    }
    return null;
}

function normalizeChipText(value) {
    return String(value ?? '').toLowerCase().replace(/[^a-z0-9]+/g, ' ').trim();
}

export function chipMatchesLabel(chip, label) {
    const wanted = normalizeChipText(label);
    if (!wanted) {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Use a longer, more specific --pick label that matches only one option.
  2. Inspect the 'Matches: ...' detail in the error and pick one of the listed titles, disambiguating by a distinguishing suffix.
  3. If options are genuinely duplicated, shorten or retype the composer text so the picker shows fewer candidates.

Example fix

// before
--pick "review"
// CommandExecutionError: Picker option "review" is ambiguous. Matches: review, Review

// after
--pick "review PR feedback"
Defensive patterns

Strategy: fallback

Try / catch

try {
  await codexSend({ text, pick });
} catch (e) {
  if (e instanceof CommandExecutionError && /ambiguous/.test(e.message)) {
    const matches = e.detail.match(/Matches: (.*)/)?.[1]?.split(', ') ?? [];
    if (matches.length === 1) return codexSend({ text, pick: matches[0] });
    console.error('Pick one exactly:', matches);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling send with --pick whose trimmed/lowercased label exactly equals the title of two or more open picker options, e.g. duplicate option titles rendered in the picker.

Common situations: Two picker entries share the same title (e.g. similarly named slash commands or repeated suggestions); using a very short/generic label like 'fix' that matches multiple items verbatim.

Related errors


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