jackwener/OpenCLI · error · CommandExecutionError

Settings button not found

Error message

Settings button not found

What it means

Thrown by the qoder settings UI command when neither clicking visible text 'Settings' nor the aria-label fallback button[aria-label="Settings"] succeeds. The command raises CommandExecutionError('Settings button not found') because the settings panel can't be opened. Both the text-based and attribute-based selectors missed the real button.

Source

Thrown at clis/qoder/ui.js:129

});

// -------- settings --------
cli({
    site: 'qoder',
    name: 'settings',
    access: 'write',
    description: 'Click the Settings button in the Qoder sidebar.',
    domain: 'localhost',
    strategy: Strategy.UI,
    browser: true,
    args: [],
    columns: ['Status'],
    func: async (page) => {
        const res = await evaluateQoder(page, clickByTextScript(['Settings']));
        if (!res?.ok) {
            // Fallback: try aria-label.
            const ariaRes = await evaluateQoder(page, clickFirstScript(['button[aria-label="Settings"]']));
            if (!ariaRes?.ok) throw new CommandExecutionError('Settings button not found', '');
        }
        await page.wait(0.5);
        return [{ Status: 'clicked' }];
    },
});

// -------- knowledge --------
cli({
    site: 'qoder',
    name: 'knowledge',
    access: 'write',
    description: 'Open the Knowledge view (Qoder\'s personal/team knowledge base).',
    domain: 'localhost',
    strategy: Strategy.UI,
    browser: true,
    args: [],
    columns: ['Status'],
    func: async (page) => {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Inspect the live DOM for the settings control and update both the text array and the aria-label selector.
  2. Add common localized variants (e.g. '设置') and attribute selectors like [data-testid="settings"], button[title="Settings"].
  3. Open any parent menu/avatar dropdown before clicking Settings.
  4. Wait for the page to fully load, and check the control isn't hover-gated in headless.

Example fix

// before
const ariaRes = await evaluateQoder(page, clickFirstScript(['button[aria-label="Settings"]']));
// after
const ariaRes = await evaluateQoder(page, clickFirstScript(['button[aria-label="Settings"]', 'button[title="Settings"]', '[data-testid="settings-button"]', 'button[aria-label="设置"]']));
Defensive patterns

Strategy: fallback

Validate before calling

const settingsBtn = await page.evaluate(`Array.from(document.querySelectorAll('button')).some(b => /settings/i.test(b.textContent || '') || b.getAttribute('aria-label') === 'Settings')`);
if (!settingsBtn) console.warn('Settings control not visible; it may live behind a menu');

Type guard

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

Try / catch

try {
  await openSettings(page);
} catch (e) {
  if (/Settings button not found/.test(String(e.message))) console.warn('Open the avatar/user menu first, then retry');
  else throw e;
}

Prevention

When it happens

Trigger: The settings entry is an icon-only gear button with a different aria-label; the button lives inside a menu that must be opened first; the settings text is localized; the button is hidden until hover; Qoder update changed the label.

Common situations: Localized UI (e.g. 设置 instead of Settings); settings behind a user/avatar dropdown; headless mode where hover-revealed controls stay hidden; page not fully loaded.

Related errors


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