jackwener/OpenCLI · warning · EmptyResultError
gmail labels
gmail labels
Error message
Gmail returned no labels
What it means
listLabels() collects labels from Gmail's DOM captures, falls back to a rendered-labels scrape, dedupes, and throws EmptyResultError ('gmail labels') if nothing was found. It indicates Gmail loaded but produced no label data the library could parse.
Source
Thrown at clis/gmail/utils.js:555
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);
const fromUrl = raw.match(/\/(?:[a-f\d]{10,})$/i)?.[0]?.slice(1);
if (fromUrl) return fromUrl.toLowerCase();
if (/^[a-f\d]{10,}$/i.test(raw)) return raw.toLowerCase();
const sync = raw.replace(/^#/, '').match(/^thread-f:(\d+)$/);
if (sync) return BigInt(sync[1]).toString(16);
throw new ArgumentError('thread must be a Gmail thread id from `gmail search` or a Gmail thread URL');
}
export async function fetchThread(page, target, account = 0) {
const legacyId = legacyThreadId(target);
await ensureGmailReady(page, account, 'thread');
await installGmailCapture(page, account, 'fd', 'thread');
const targetState = unwrapBrowserResult(await page.evaluate(`async () => {View on GitHub (pinned to 49907e53dc)
Solutions
- Retry after ensuring Gmail is fully loaded (increase wait/retry)
- Navigate to a mailbox view first so the labels UI renders
- Update the library if Google changed the Gmail DOM
- Verify the account is fully set up and logged in
Example fix
// before
const labels = await listLabels(page);
// after
await ensureGmailReady(page, 0, 'labels'); // or explicit pre-navigation
const labels = await listLabels(page);
if (labels.length === 0) console.warn('no labels found — UI may have changed'); Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
null
Try / catch
try { labels = await listLabels(page); }
catch (e) { if (e instanceof EmptyResultError) { labels = []; await page.sleep(2); labels = await listLabels(page).catch(() => []); } else throw e; } Prevention
- Ensure Gmail is fully loaded/logged in before listing labels
- Retry once on empty label results
- Watch for Gmail DOM changes requiring a library update
When it happens
Trigger: listLabels(page, account) when both the capture-based parse and the renderedLabels fallback return nothing — e.g. Gmail not fully loaded, a Gmail UI change breaking parsers, or an account/page state with no labels in view.
Common situations: Automating a fresh account where the page redirects to a welcome/empty state; Google changing the Gmail DOM; slow load where the wait for captures times out to zero results.
Related errors
- The Gmail thread has no attachments
- Gmail returned a malformed label at index ${index}
- gmail search
- gmail thread
- No prices returned for train_no=${trainNo} ${fromStation.nam
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/26eb3f6d26f78d47.
Report an issue: GitHub.