jackwener/OpenCLI · error · CommandExecutionError

No account button detected. Pass --username <name> explicitl

Error message

No account button detected. Pass --username <name> explicitly.

What it means

In the Qoder 'account' flow, the adapter tries to auto-detect the logged-in username by scraping visible candidate buttons; if no candidate label is found (label is empty), it throws CommandExecutionError('No account button detected. Pass --username <name> explicitly.'). The library throws this because it cannot safely guess which button is the account menu.

Source

Thrown at clis/qoder/ui.js:274

        // for any short button text that doesn't match other known controls.
        let label = String(kwargs?.username || '').trim();
        if (!label) {
            // Heuristic discovery.
            label = await evaluateQoder(page, `(() => {
        ${IS_VISIBLE_JS}
        const btns = Array.from(document.querySelectorAll('button')).filter(isVisible);
        const known = new Set(['Pin', 'Copy', 'New Quest', 'Search', 'Settings', 'View all', 'Knowledge', 'Marketplace', 'Credits Usage', 'Open Editor', 'Add Workspace', 'More Actions', 'Send message', 'Prompt Enhance', 'Voice input', 'button']);
        const candidate = btns.find((b) => {
          const tx = (b.innerText || '').trim();
          if (!tx || tx.length > 30 || tx.includes('⌘') || known.has(tx)) return false;
          if (/^(New|Open|Add|Save|Edit|Cancel|OK|Close)/.test(tx)) return false;
          return true;
        });
        return candidate ? (candidate.innerText || '').trim() : '';
      })()`);
        }
        if (!label) {
            throw new CommandExecutionError('No account button detected. Pass --username <name> explicitly.', '');
        }
        // Click the username button
        const clickRes = await evaluateQoder(page, clickByTextScript([label], { exact: true, maxLen: 60 }));
        if (!clickRes?.ok) throw new CommandExecutionError(`Click on account button "${label}" failed`, '');
        await page.wait(0.5);
        const items = requireArrayResult(await evaluateQoder(page, `(() => {
      ${IS_VISIBLE_JS}
      const popovers = Array.from(document.querySelectorAll('[role="menu"], [role="dialog"], [class*="popover"i], [class*="dropdown"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('button, [role="menuitem"], a'))
        .filter(isVisible)
        .map((b) => (b.innerText || b.textContent || '').trim().replace(/\\s+/g, ' '))
        .filter(Boolean);
    })()`), 'qoder account');
        try { await page.evaluate(`document.body.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }));`); } catch {}
        const rows = [{ Field: 'Username', Value: label }];

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass the username explicitly: run the command with --username <name> as the error instructs.
  2. Sign in to Qoder first, then retry without the flag.
  3. Wait for the UI to fully render before running the account command.
  4. If the button is icon-only, the auto-detection cannot work — always use --username in that setup.
  5. Update the detection script in clis/qoder/ui.js if Qoder moved the account control.

Example fix

// before
opencli qoder account
// after (explicit username)
opencli qoder account --username alice
Defensive patterns

Strategy: validation

Validate before calling

// Validate inputs before invoking the account command
function assertAccountArgs(args) {
  if (!args.username) {
    throw new Error('Auto-detection may fail (icon-only avatar / logged out). Pass --username explicitly.');
  }
  if (typeof args.username !== 'string' || !args.username.trim()) {
    throw new Error('--username must be a non-empty string matching the UI display name.');
  }
}

Type guard

function hasUsernameArg(args) {
  return typeof args === 'object' && args !== null &&
    typeof args.username === 'string' && args.username.trim().length > 0;
}

Try / catch

try {
  await cli.run(['qoder', 'account']);
} catch (e) {
  if (String(e.message).includes('No account button detected')) {
    await cli.run(['qoder', 'account', '--username', process.env.QODER_USER]);
  } else throw e;
}

Prevention

When it happens

Trigger: Running the account command without --username when: the user is not signed in to Qoder, the account widget shows only an avatar icon with no text, the account popover is behind a modal, or the heuristic that extracts candidate.innerText returns an empty string.

Common situations: Fresh Qoder install / logged-out state; account button rendered as an icon-only avatar (no innerText); UI not yet rendered when the probe runs; Qoder update moved the account control out of the scanned container.

Related errors


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