jackwener/OpenCLI · error · CommandExecutionError

More Actions button not found

Error message

More Actions button not found

What it means

The Qoder 'more-actions' UI command clicks a visible 'More Actions' element to open the context menu, then lists its items. If clickByTextScript returns {ok:false} (no matching visible element), it throws CommandExecutionError('More Actions button not found'). The trigger button for the actions menu was not found in the DOM.

Solutions

  1. Open the Qoder view where More Actions is available (e.g. select a Quest/element that exposes it) and retry.
  2. Add icon-button selector fallbacks via clickFirstScript(['[aria-label*="more" i]', '[title*="more" i]', 'button[aria-haspopup="menu"]']).
  3. Add a startup wait and re-run the command.
  4. Verify the current control's label/selector in CDP DevTools and update clis/qoder/ui.js.
  5. Dismiss any modal blocking the toolbar.

Example fix

// before
const res = await evaluateQoder(page, clickByTextScript(['More Actions']));
// after: text + icon fallbacks
let res = await evaluateQoder(page, clickByTextScript(['More Actions']));
if (!res?.ok) res = await evaluateQoder(page, clickFirstScript(['[aria-label*="more" i]', '[aria-label*="action" i]']));
Defensive patterns

Strategy: fallback

Validate before calling

async function moreActionsAvailable(page) {
  const probe = await page.evaluate(`(() => {
    const byText = Array.from(document.querySelectorAll('button, [role="button"]'))
      .some(b => (b.innerText||'').toLowerCase().includes('more actions'));
    const byIcon = !!document.querySelector('[aria-label*="more" i], [title*="more" i]');
    return byText || byIcon;
  })()`);
  if (probe !== true) throw new Error('More Actions control not present in current view.');
}

Type guard

function isClickResult(res) {
  return res !== null && typeof res === 'object' && typeof res.ok === 'boolean';
}

Try / catch

try {
  await cli.run(['qoder', 'more-actions']);
} catch (e) {
  if (String(e.message).includes('More Actions button not found')) {
    console.error('Navigate to the view exposing More Actions (or select an item) and retry.');
  } else throw e;
}

Prevention

When it happens

Trigger: Running 'more-actions' when the More Actions control is hidden (no selection/context in the Qoder UI), the UI is still loading, the label is icon-only ('...' without text), or the wording changed in a Qoder update.

Common situations: Qoder update replaced the text button with an ellipsis icon button (no innerText to match); menu only available in certain views; window minimized so isVisible fails; welcome screen covering the toolbar.

Related errors


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

Appendix: source

Thrown at clis/qoder/ui.js:313

        });
        return rows;
    },
});

// -------- more-actions --------
cli({
    site: 'qoder',
    name: 'more-actions',
    access: 'read',
    description: 'Click the "More Actions" button and list its menu items.',
    domain: 'localhost',
    strategy: Strategy.UI,
    browser: true,
    args: [],
    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)