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
- Pass a non-empty search query, e.g. queryThreads(page, 'from:me newer_than:7d')
- Trim/validate the query at your CLI/entry point before calling queryThreads
- 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
- Validate CLI --query as required before invoking the library
- Trim user input and reject whitespace-only strings early
- Default to a broad query (e.g. 'in:anywhere') rather than empty when none given
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
- thread must be a Gmail thread id from `gmail search` or a Gm
- archive search sort must be one of ${SORT_OPTIONS.join(', ')
- archive search mediatype must be one of ${MEDIATYPES.join(',
- archive search limit must be a positive integer
- archive search limit must be <= 100
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/fe6472dfd914c805.
Report an issue: GitHub.