jackwener/OpenCLI · error · CommandExecutionError

No picker option matched.

Error message

No picker option matched.

What it means

The picker opened, but findUniquePickerOption returned null: no option's title matched exactly and no option's text contained the wanted --pick label. The library throws CommandExecutionError including the wanted label and all available option titles so you can correct the label.

Source

Thrown at clis/codex/send.js:160

          .filter((it) => it instanceof HTMLElement && it.offsetParent);
        if (items.length) break;
        await wait(75);
      }
      // Picker titles are split into per-character spans for match
      // highlighting, so read the leading truncate div for the title and the
      // concatenated textContent (title plus description) for substrings.
      return items.map((el) => {
        const text = (el.textContent || '').replace(/\\s+/g, ' ').trim();
        const lead = el.querySelector('[class*="truncate"]');
        return { title: lead ? (lead.textContent || '').replace(/\\s+/g, ' ').trim() : text, text };
      });
    })()`));
            if (!Array.isArray(options) || options.length === 0) {
                throw new CommandExecutionError('Codex picker did not open after typing the command.', 'Check that the text opens a picker, or drop --pick.');
            }
            picked = findUniquePickerOption(options, pick);
            if (!picked) {
                throw new CommandExecutionError('No picker option matched.', `wanted=${pick} available=${JSON.stringify(options.map((option) => option.title))}`);
            }
            const clicked = unwrapEvaluateResult(await page.evaluate(`(() => {
      const items = Array.from(document.querySelectorAll('${PICKER_ITEM_SELECTOR}'))
        .filter((it) => it instanceof HTMLElement && it.offsetParent);
      const target = items[${picked.index}];
      if (!target) return false;
      const rect = target.getBoundingClientRect();
      const init = {
        bubbles: true, cancelable: true, button: 0, buttons: 1,
        clientX: Math.round(rect.left + rect.width / 2),
        clientY: Math.round(rect.top + rect.height / 2),
      };
      // The picker only responds to the full pointer chain, and deferring it
      // keeps the eval response ahead of the re-render that closes the picker.
      Promise.resolve().then(() => {
        try {
          target.dispatchEvent(new PointerEvent('pointerdown', { ...init, pointerType: 'mouse' }));
          target.dispatchEvent(new MouseEvent('mousedown', init));

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Read the 'available=[...]' list in the error and use one of those titles (or an unambiguous substring) as --pick.
  2. Fix typos and remove punctuation from the --pick label.
  3. Adjust the composer text so the picker lists the option you intend to select.
  4. Drop --pick if you don't need a picker selection at all.

Example fix

// before
$ codex send --pick "plan mode" "/rev"
// No picker option matched. wanted=plan mode available=["Review","Resolve"]

// after
$ codex send --pick "Review" "/rev"
Defensive patterns

Strategy: validation

Validate before calling

const knownTitles = ['Review', 'Resolve', 'Plan mode']; // titles captured from the picker
const wanted = (pick || '').replace(/\s+/g, ' ').trim().toLowerCase();
if (pick && !knownTitles.some(t => t.toLowerCase().includes(wanted))) {
  throw new Error(`Unknown picker option "${pick}". Available: ${knownTitles.join(', ')}`);
}

Try / catch

try {
  await codexSend({ text, pick });
} catch (e) {
  if (e instanceof CommandExecutionError && /No picker option matched/.test(e.message)) {
    const available = JSON.parse(e.detail.match(/available=(\[.*\])/)?.[1] ?? '[]');
    console.error('Use one of:', available);
    process.exitCode = 2;
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling send with --pick "label" where the opened picker has options but none match the label exactly or as a substring (after whitespace-collapsing and lowercasing).

Common situations: Typo in the label; wrong casing assumptions are fine but wrong wording isn't (e.g. 'planning' vs 'Plan'); the picker shows different options than expected because the composer text differs; non-English UI; trailing punctuation in the label.

Related errors


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