{"record":{"id":"7a21e5a0039619a7","repo":"jackwener/OpenCLI","slug":"google-sso-cookies-sid-sapisid-missing","errorCode":null,"errorMessage":"Google SSO cookies (SID + SAPISID) missing","messagePattern":"Google SSO cookies \\(SID \\+ SAPISID\\) missing","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/notebooklm/auth.js","lineNumber":14,"sourceCode":"import { AuthRequiredError, CommandExecutionError } from '@jackwener/opencli/errors';\nimport { registerSiteAuthCommands } from '../_shared/site-auth.js';\nimport { NOTEBOOKLM_DOMAIN, NOTEBOOKLM_HOME_URL } from './shared.js';\nimport { unwrapNotebooklmEvaluateResult } from './rpc.js';\n\nasync function hasNotebookLmSsoCookies(page) {\n  const cookies = await page.getCookies({ url: NOTEBOOKLM_HOME_URL });\n  const names = new Set(cookies.map(c => c.name));\n  return names.has('SID') && names.has('SAPISID');\n}\n\nasync function verifyNotebookLmIdentity(page) {\n  if (!await hasNotebookLmSsoCookies(page)) {\n    throw new AuthRequiredError(NOTEBOOKLM_DOMAIN, 'Google SSO cookies (SID + SAPISID) missing');\n  }\n  await page.goto(NOTEBOOKLM_HOME_URL);\n  await page.wait(3);\n  const probe = unwrapNotebooklmEvaluateResult(await page.evaluate(`\n    (() => {\n      if (/accounts\\\\.google\\\\.com\\\\/ServiceLogin/.test(location.href) || /accounts\\\\.google\\\\.com\\\\/signin/i.test(location.href)) {\n        return { kind: 'auth', detail: 'NotebookLM redirected to Google sign-in' };\n      }\n      const acctEl = document.querySelector('a[aria-label^=\"Google Account:\"], a[aria-label*=\"Google 账号:\"]');\n      if (!acctEl) {\n        return { kind: 'auth', detail: 'NotebookLM missing Google Account button' };\n      }\n      const label = acctEl.getAttribute('aria-label') || '';\n      const nameMatch = label.match(/Google Account:\\\\s*([^\\\\n\\\\(]+?)(?:\\\\s*\\\\n|\\\\s*\\\\()/i) ||\n                        label.match(/Google 账号:\\\\s*([^\\\\n\\\\(]+?)(?:\\\\s*\\\\n|\\\\s*\\\\()/i);\n      const name = nameMatch ? nameMatch[1].trim() : '';\n      const authuserMatch = location.href.match(/[?&]authuser=(\\\\d+)/);\n      const authuser = authuserMatch ? Number(authuserMatch[1]) : 0;","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/notebooklm/auth.js#L1-L32","documentation":"verifyNotebookLmIdentity first checks the browser context for Google SSO cookies SID and SAPISID. If either is absent it throws AuthRequiredError for the notebooklm domain, because NotebookLM API/RPC calls cannot be authenticated without them.","triggerScenarios":"Running any notebooklm command (or a poll/quick check) when the browser profile was never logged into Google, cookies were cleared, or a different profile (authuser) is active.","commonSituations":"Fresh automation container with no logged-in profile; incognito session; Google expired/revoked cookies; running headless before an initial interactive `notebooklm login`.","solutions":["Run the site's login flow (e.g. `notebooklm login`) and complete Google SSO interactively.","Point the CLI at a browser profile that is already logged into Google.","Re-login if cookies expired; SID/SAPISID must both be present in the cookie jar for accounts.google.com / notebooklm context."],"exampleFix":"// before\nrunCommand('notebooklm create --title Notes')\n// after\nrunCommand('notebooklm login')  // completes SSO, sets SID + SAPISID\nrunCommand('notebooklm create --title Notes')","handlingStrategy":"try-catch","validationCode":"const cookies = await browser.cookies.getAll({ domain: 'google.com' });\nif (!cookies.some(c => c.name === 'SID') || !cookies.some(c => c.name === 'SAPISID')) await runLogin();","typeGuard":"function hasSsoCookies(cookies) {\n  const names = new Set(cookies.map(c => c.name));\n  return names.has('SID') && names.has('SAPISID');\n}","tryCatchPattern":"try {\n  await notebooklm.create({ title });\n} catch (e) {\n  if (String(e.message).includes('Google SSO cookies')) {\n    await notebooklmLogin(); // interactive SSO\n    return notebooklm.create({ title });\n  }\n  throw e;\n}","preventionTips":["Run the login flow once per fresh browser profile before automation.","Reuse a persistent, logged-in profile instead of incognito.","Check cookie presence as a quick pre-flight before commands."],"tags":["auth","cookies","google-sso","notebooklm"],"backgroundTag":"missing-auth-cookies","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}