jackwener/OpenCLI · error · EmptyResultError

qoder more-actions

Error message

qoder more-actions

What it means

After opening the More Actions menu, the Qoder 'more-actions' command extracts menu items and passes them to requireArrayResult with the label 'qoder more-actions'. If page.evaluate returns a non-array (unexpected result shape, e.g. the script errored or the CDP payload was wrapped unexpectedly), requireArrayResult throws CommandExecutionError('qoder more-actions: unexpected evaluate result shape'). The bracketed message 'qoder more-actions' is that label prefix.

Source

Thrown at clis/qoder/ui.js:328

    columns: ['Index', 'Item'],
    func: async (page) => {
        const res = await evaluateQoder(page, clickByTextScript(['More Actions']));
        if (!res?.ok) throw new CommandExecutionError(res?.reason || 'More Actions button not found', '');
        await page.wait(0.4);
        const items = requireArrayResult(await evaluateQoder(page, `(() => {
      ${IS_VISIBLE_JS}
      const popovers = Array.from(document.querySelectorAll('[role="menu"], [role="dialog"], [class*="popover"i], [class*="menu"i]')).filter(isVisible)
        .filter((el) => { const r = el.getBoundingClientRect(); return r.width < 500 && r.height < 600; });
      if (!popovers.length) return [];
      const pop = popovers[popovers.length - 1];
      return Array.from(pop.querySelectorAll('[role="menuitem"], button'))
        .filter(isVisible)
        .map((b) => (b.innerText || b.textContent || '').trim().replace(/\\s+/g, ' '))
        .filter(Boolean);
    })()`), 'qoder more-actions');
        try { await page.evaluate(`document.body.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }));`); } catch {}
        if (!items.length) {
            throw new EmptyResultError('qoder more-actions', 'Menu opened but no items detected.');
        }
        return items.map((it, i) => ({ Index: i + 1, Item: it }));
    },
});

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Ensure the menu stays open until the scrape completes (avoid moving focus/clicking elsewhere) and retry.
  2. Keep the Qoder window open and attached over CDP for the whole command.
  3. Wrap the in-page script in try/catch returning [] so evaluate always yields an array, then surface 'no items' via EmptyResultError instead.
  4. Check that unwrapEvaluateResult handles the payload shape your CDP layer returns.
  5. Re-run the command; transient focus races are the usual cause.

Example fix

// before
const items = requireArrayResult(await evaluateQoder(page, scrapeScript), 'qoder more-actions');
// after: tolerate non-array and report empty
const raw = await evaluateQoder(page, `(() => { try { ...scrape...; return list; } catch (e) { return []; } })()`);
const items = Array.isArray(raw) ? raw : [];
Defensive patterns

Strategy: try-catch

Validate before calling

async function menuStillOpen(page) {
  const open = await page.evaluate(`(() =>
    !!document.querySelector('[role="menu"]:not([hidden])')
  )()`);
  if (open !== true) throw new Error('More Actions menu already closed — re-open before scraping.');
}

Type guard

function isMenuItemArray(value) {
  return Array.isArray(value) && value.every((v) => typeof v === 'string');
}

Try / catch

try {
  const items = await cli.run(['qoder', 'more-actions']);
} catch (e) {
  if (String(e.message).includes('qoder more-actions')) {
    // menu raced closed or evaluate returned a non-array; retry once after reopening
    await cli.run(['qoder', 'more-actions']);
  } else throw e;
}

Prevention

When it happens

Trigger: The menu-scraping IIFE throws inside the page (evaluate returns an error object instead of an array), the CDP evaluate wrapper returns {session,data} with data not an array, or the page navigated/closed mid-evaluate.

Common situations: Menu closed before the scrape ran (Escape/focus change), causing a script branch returning undefined; Qoder window closed between click and scrape; CDP session detached; a Qoder update changed DOM so the query throws inside the page context.

Related errors


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