jackwener/OpenCLI · error · CommandExecutionError

search open failed

Error message

search open failed

What it means

Thrown by the qoder search command when the initial click on the 'Search' text (to open the search palette) fails. clickByTextScript found no visible 'Search' element, so evaluateQoder returned ok:false and the command raises CommandExecutionError with reason or the 'search open failed' fallback. The rest of the search flow (typing, reading results) cannot proceed without the palette open.

Source

Thrown at clis/qoder/ui.js:78

cli({
    site: 'qoder',
    name: 'search',
    access: 'read',
    description: 'Open Qoder Search palette (⌘P), type a query, return matched options.',
    domain: 'localhost',
    strategy: Strategy.UI,
    browser: true,
    args: [
        { name: 'query', positional: true, required: true, help: 'Search text' },
        { name: 'limit', type: 'int', required: false, default: 20 },
    ],
    columns: ['Index', 'Item'],
    func: async (page, kwargs) => {
        const query = String(kwargs?.query || '').trim();
        if (!query) throw new ArgumentError('query', 'is required');
        const limit = parsePositiveInt(kwargs?.limit, 20, '--limit');
        const openRes = await evaluateQoder(page, clickByTextScript(['Search']));
        if (!openRes?.ok) throw new CommandExecutionError(openRes?.reason || 'search open failed', '');
        await page.wait(0.5);
        // Type into the visible input (usually the most-recently mounted one).
        const fillRes = await evaluateQoder(page, `(() => {
      ${IS_VISIBLE_JS}
      const inputs = Array.from(document.querySelectorAll('input[type="text"], input[type="search"], input:not([type])')).filter(isVisible);
      const input = inputs[inputs.length - 1];
      if (!input) return { ok: false, reason: 'No input visible.' };
      const setter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set;
      setter.call(input, ${JSON.stringify(query)});
      input.dispatchEvent(new Event('input', { bubbles: true }));
      input.dispatchEvent(new Event('change', { bubbles: true }));
      return { ok: true };
    })()`);
        if (!fillRes?.ok) throw new CommandExecutionError(fillRes?.reason || 'search type failed', '');
        await page.wait(0.8);
        const items = requireArrayResult(await evaluateQoder(page, `(() => {
      ${IS_VISIBLE_JS}
      // Search palette results: prefer [role=option], else any clickable row in the modal.

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Confirm the search control's actual text/aria-label in the UI and update clickByTextScript.
  2. Use clickFirstScript with selectors like input[type="search"] or [aria-label="Search"] as a fallback.
  3. Add a wait for the page/search control to be present before clicking.
  4. Alternatively trigger the search keyboard shortcut (e.g. Ctrl/Cmd+K) via keydown dispatch if text click keeps failing.

Example fix

// before
const openRes = await evaluateQoder(page, clickByTextScript(['Search']));
// after
let openRes = await evaluateQoder(page, clickByTextScript(['Search']));
if (!openRes?.ok) openRes = await evaluateQoder(page, clickFirstScript(['[aria-label="Search"]', 'input[type="search"]']));
if (!openRes?.ok) throw new CommandExecutionError(openRes?.reason || 'search open failed', '');
Defensive patterns

Strategy: fallback

Validate before calling

const hasSearch = await page.evaluate(`Array.from(document.querySelectorAll('button, [role="button"]')).some(el => /search/i.test(el.textContent || el.getAttribute('aria-label') || ''))`);
if (!hasSearch) console.warn('No search control found on page');

Type guard

function isClickOk(res) { return Boolean(res && res.ok === true); }

Try / catch

try {
  await search(page, query);
} catch (e) {
  if (/search open failed/.test(String(e.message))) {
    await page.evaluate(`document.dispatchEvent(new KeyboardEvent('keydown', { key: 'k', ctrlKey: true, bubbles: true }))`);
    return searchFromOpenPalette(page, query);
  }
  throw e;
}

Prevention

When it happens

Trigger: No visible element containing 'Search' text exists (icon-only search control, different label); the search feature is unavailable on the current page; the page is still loading; Qoder update renamed the search entry point; the keyboard shortcut is the only way to open search.

Common situations: Qoder redesign replacing the text-labeled search button with an icon; localized UI; user not on the main quest view; slow load in headless mode.

Related errors


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