{"record":{"id":"31f9edfefd50449f","repo":"jackwener/OpenCLI","slug":"browser-session-required-for-gmail-attachments","errorCode":null,"errorMessage":"Browser session required for gmail attachments","messagePattern":"Browser session required for gmail attachments","errorType":"error_code","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/gmail/attachments.js","lineNumber":21,"sourceCode":"import { fetchThread, parseAccount } from './utils.js';\n\ncli({\n  site: 'gmail',\n  name: 'attachments',\n  access: 'read',\n  description: 'List attachment metadata for a Gmail thread',\n  domain: 'mail.google.com',\n  strategy: Strategy.INTERCEPT,\n  browser: true,\n  navigateBefore: false,\n  siteSession: 'persistent',\n  args: [\n    { name: 'thread', type: 'string', positional: true, required: true, help: 'Thread id from gmail search, legacy id, or Gmail thread URL' },\n    { name: 'account', type: 'int', default: 0, help: 'Gmail account index from the /mail/u/<index>/ URL' },\n  ],\n  columns: ['messageId', 'attachmentId', 'name', 'mimeType', 'size'],\n  func: async (page, kwargs) => {\n    if (!page) throw new CommandExecutionError('Browser session required for gmail attachments');\n    const messages = await fetchThread(page, kwargs.thread, parseAccount(kwargs.account));\n    const rows = messages.flatMap((message) => message.attachments.map((attachment) => ({\n      messageId: message.messageId,\n      ...attachment,\n    })));\n    if (rows.length === 0) {\n      throw new EmptyResultError('gmail attachments', 'The Gmail thread has no attachments');\n    }\n    return rows;\n  },\n});\n","sourceCodeStart":3,"sourceCodeEnd":33,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/gmail/attachments.js#L3-L33","documentation":"The gmail attachments command requires a live browser session because attachments are scraped from the Gmail web UI, but its func received page === null. The CLI throws CommandExecutionError up front instead of failing later inside fetchThread, indicating the command was invoked without a browser context attached.","triggerScenarios":"Calling the gmail attachments command with no active browser session — e.g. running in headless/offline mode, browser not launched, or session registration skipped — so the func's `if (!page)` guard fires.","commonSituations":"Running the CLI outside the browser-backed environment; browser session crashed or was closed before invoking; forgetting to start/connect the persistent site session for gmail; automation harness passing null as the page handle.","solutions":["Start/attach the browser session (persistent site session for gmail) before running the command","Verify the browser process is running and the page handle is passed to the command","Re-run the command after any browser crash to re-establish the session","Guard callers: check session/page availability before invoking gmail commands"],"exampleFix":"// before\nawait run('gmail-attachments', { thread: threadId }); // page was null\n// after\nconst page = await getOrLaunchBrowserSession('gmail');\nif (!page) throw new Error('launch the gmail browser session first');\nawait run('gmail-attachments', { thread: threadId }, { page });","handlingStrategy":"validation","validationCode":"if (!page || typeof page.evaluate !== 'function') {\n  throw new Error('gmail attachments needs a live browser page — attach the gmail session first');\n}","typeGuard":"function isLivePage(p) {\n  return !!p && typeof p.evaluate === 'function' && typeof p.goto === 'function';\n}","tryCatchPattern":"try {\n  const rows = await runGmailAttachments(threadId);\n} catch (e) {\n  if (/Browser session required/.test(e.message)) {\n    await ensureBrowserSession('gmail');\n    return runGmailAttachments(threadId);\n  }\n  throw e;\n}","preventionTips":["Always launch/attach the persistent browser session before gmail commands","Health-check the page handle (isLivePage) before each invocation","Restart the session after any browser crash","Centralize session acquisition instead of passing raw null pages","Run browser-backed commands only in the browser-enabled environment"],"tags":["browser","session","gmail","precondition"],"backgroundTag":"browser-session-required","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}