jackwener/OpenCLI · warning · EmptyResultError
gmail search
gmail search
Error message
No threads matched "${normalizedQuery}" What it means
EmptyResultError with code 'gmail search' thrown when a search completed successfully but matched zero threads. The library treats 'no results' as a distinct, expected condition so callers can handle it separately from real failures.
Source
Thrown at clis/gmail/utils.js:542
'bv',
pageNumber === 1 ? 'thread list' : `thread pagination page ${pageNumber}`,
);
const pageRows = bodies.flatMap(parseBatchView);
let added = 0;
for (const row of pageRows) {
if (seen.has(row.threadId)) continue;
seen.add(row.threadId);
rows.push(row);
added += 1;
if (rows.length >= limit) return rows;
}
if (pageNumber > 1 && added === 0) {
throw new CommandExecutionError(`Gmail thread pagination page ${pageNumber} repeated an earlier response; refusing partial results`);
}
if (pageRows.length < PAGE_SIZE) break;
}
if (rows.length === 0) {
throw new EmptyResultError('gmail search', `No threads matched "${normalizedQuery}"`);
}
return rows.slice(0, limit);
}
export async function listLabels(page, account = 0) {
await ensureGmailReady(page, account, 'labels');
await installGmailCapture(page, account, 'bv', 'labels');
await submitSearch(page, 'in:anywhere', 'labels');
const bodies = await waitGmailCaptures(page, 'bv', 'labels');
const labels = bodies.flatMap(parseLabels);
const fallback = labels.length === 0 ? await renderedLabels(page, account) : [];
const unique = [...new Map([...labels, ...fallback].map((row) => [row.id, row])).values()];
if (unique.length === 0) throw new EmptyResultError('gmail labels', 'Gmail returned no labels');
return unique;
}
export function legacyThreadId(value) {
const raw = cleanString(value);View on GitHub (pinned to 49907e53dc)
Solutions
- Broaden the query (remove filters, widen the date range)
- Verify the label/address in the query exists in the target account
- Catch EmptyResultError and treat it as a valid empty outcome
- Check you are on the expected account index (account option)
Example fix
// before
const rows = await queryThreads(page, 'from:ghost@nowhere.test');
// after
try {
const rows = await queryThreads(page, 'from:ghost@nowhere.test');
} catch (e) {
if (e instanceof EmptyResultError) return [];
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
null
Try / catch
try { rows = await queryThreads(page, q); }
catch (e) { if (e instanceof EmptyResultError && e.code === 'gmail search') return []; throw e; } Prevention
- Treat EmptyResultError as a normal empty outcome, not a crash
- Broaden queries programmatically when zero results are acceptable to escalate
- Test queries against the target account before bulk automation
When it happens
Trigger: queryThreads(page, query) where the query matches no mail: overly narrow filters, wrong label names, mail in an account that has none, misspelled Gmail operators.
Common situations: Searching a secondary/test account that has no mail; using operators like label:foo where the label doesn't exist; date filters (older_than/newer_than) excluding everything.
Related errors
- No 12306 stations match "${keyword}"
- ${label}
- No papers found for author "${authorText}". Try alternate sp
- No papers found. Try a different keyword.
- crates search
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/19067f6b2f40d32c.
Report an issue: GitHub.