jackwener/OpenCLI · error · ArgumentError

Gmail search query cannot be empty

Error message

Gmail search query cannot be empty

What it means

queryThreads() cleans the provided search string with cleanString() and throws ArgumentError when the result is empty. The library refuses to issue an empty Gmail search because Gmail's UI would either reject it or return an unfiltered inbox listing, which is almost never what the caller intended. It is a fail-fast input validation error.

Source

Thrown at clis/gmail/utils.js:481

    throw new CommandExecutionError(`Gmail ${operation} requires native browser input`);
  }
  await page.nativeType(query);
  const actual = unwrapBrowserResult(await page.evaluate(`() => document.querySelector('input[name="q"]')?.value || ''`), `${operation} search input verification`);
  if (actual !== query) throw new CommandExecutionError(`Gmail ${operation} could not set the search query exactly`);
  if (typeof page.cdp === 'function') {
    const key = { key: 'Enter', code: 'Enter', windowsVirtualKeyCode: 13, nativeVirtualKeyCode: 13 };
    await page.cdp('Input.dispatchKeyEvent', { type: 'rawKeyDown', ...key });
    await page.cdp('Input.dispatchKeyEvent', { type: 'keyUp', ...key });
  } else if (typeof page.nativeKeyPress === 'function') {
    await page.nativeKeyPress('Enter');
  } else {
    throw new CommandExecutionError(`Gmail ${operation} requires native browser keyboard input`);
  }
}

export async function queryThreads(page, query, { account = 0, limit = DEFAULT_LIMIT } = {}) {
  const normalizedQuery = cleanString(query);
  if (!normalizedQuery) throw new ArgumentError('Gmail search query cannot be empty');
  await ensureGmailReady(page, account, 'thread list');
  await installGmailCapture(page, account, 'bv', 'thread list');

  const rows = [];
  const seen = new Set();
  const pages = Math.ceil(limit / PAGE_SIZE);
  for (let pageNumber = 1; pageNumber <= pages; pageNumber += 1) {
    if (pageNumber === 1) {
      await submitSearch(page, normalizedQuery, 'thread list');
    } else {
      const target = unwrapBrowserResult(await page.evaluate(`() => {
        const labels = /(older|较旧|較舊|下一页|下一頁)/i;
        const button = Array.from(document.querySelectorAll('button, [role="button"]')).find((node) => {
          const value = [node.getAttribute('aria-label'), node.getAttribute('data-tooltip'), node.getAttribute('title')]
            .filter(Boolean).join(' ');
          const rect = node.getBoundingClientRect();
          return labels.test(value) && node.getAttribute('aria-disabled') !== 'true' && rect.width > 0 && rect.height > 0;
        });

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass a non-empty search query, e.g. queryThreads(page, 'from:me newer_than:7d')
  2. Trim/validate the query at your CLI/entry point before calling queryThreads
  3. Check that the variable holding the query is actually populated (log it before the call)

Example fix

// before
await queryThreads(page, opts.query);
// after
if (!opts.query || !opts.query.trim()) throw new Error('--query is required');
await queryThreads(page, opts.query.trim());
Defensive patterns

Strategy: validation

Validate before calling

if (typeof query !== 'string' || !query.trim()) throw new Error('query must be a non-empty string');
await queryThreads(page, query.trim(), { account, limit });

Type guard

const isNonEmptyQuery = (q) => typeof q === 'string' && q.trim().length > 0;

Try / catch

try { await queryThreads(page, q); } catch (e) { if (e instanceof ArgumentError) { console.error('Provide a search query'); return; } throw e; }

Prevention

When it happens

Trigger: Calling queryThreads(page, '') or queryThreads(page, null); calling queryThreads(page, ' ') (whitespace-only, stripped by cleanString); passing a variable that is undefined/empty after template interpolation.

Common situations: Building a query string from CLI flags where the user omitted --query; concatenating filters that all evaluated to empty; a config value defaulting to '' instead of a real query.

Related errors


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