{"record":{"id":"dedeaedf854b9063","repo":"jackwener/OpenCLI","slug":"notebooklm-rpc-redirected-to-the-login-page","errorCode":null,"errorMessage":"NotebookLM RPC redirected to the login page","messagePattern":"NotebookLM RPC redirected to the login page","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/notebooklm/rpc.js","lineNumber":246,"sourceCode":"    const url = NOTEBOOKLM_RPC_PATH +\n        `?rpcids=${rpcId}&source-path=${encodeURIComponent(auth.sourcePath)}` +\n        (authuser ? `&authuser=${encodeURIComponent(authuser)}` : '') +\n        `&hl=${encodeURIComponent(options.hl ?? 'en')}` +\n        `&f.sid=${encodeURIComponent(auth.sessionId)}&rt=c`;\n    const response = await fetchNotebooklmInPage(page, url, {\n        method: 'POST',\n        headers: {\n            'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',\n        },\n        body: requestBody,\n    });\n    const requestUrl = parseTrustedNotebooklmUrl(response.requestUrl);\n    const finalUrl = parseTrustedNotebooklmUrl(response.finalUrl);\n    if (!requestUrl || requestUrl.origin !== auth.origin || requestUrl.pathname !== NOTEBOOKLM_RPC_PATH) {\n        throw new CommandExecutionError('NotebookLM RPC request resolved outside the active trusted origin');\n    }\n    if (finalUrl?.origin === auth.origin && (finalUrl.pathname === '/login' || finalUrl.pathname.startsWith('/login/'))) {\n        throw new AuthRequiredError(NOTEBOOKLM_DOMAIN, 'NotebookLM RPC redirected to the login page');\n    }\n    if (!finalUrl || finalUrl.origin !== auth.origin || finalUrl.pathname !== NOTEBOOKLM_RPC_PATH) {\n        throw new CommandExecutionError('NotebookLM RPC response redirected outside the active trusted endpoint');\n    }\n    if (response.status === 401 || response.status === 403) {\n        throw new AuthRequiredError(NOTEBOOKLM_DOMAIN, `NotebookLM RPC returned auth error (${response.status})`);\n    }\n    if (!response.ok) {\n        throw new CliError('NOTEBOOKLM_RPC', `NotebookLM RPC request failed with HTTP ${response.status}`, 'Retry from the NotebookLM home page in an already logged-in Chrome session.');\n    }\n    return {\n        auth,\n        url: requestUrl.href,\n        requestBody,\n        response,\n        result: extractNotebooklmRpcResult(response.body, rpcId),\n    };\n}","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/notebooklm/rpc.js#L228-L264","documentation":"callNotebooklmRpc checks response.finalUrl after following redirects. If the final URL is on the trusted origin but its path is /login or under /login/, NotebookLM bounced the authenticated RPC to the sign-in page, meaning the session credentials are no longer valid. It throws AuthRequiredError so the CLI can prompt for re-authentication instead of failing with a generic HTTP error.","triggerScenarios":"The Google session cookie expired or was revoked, the RPC returns a 30x redirect to /login, or the attached Chrome profile was logged out (or the user signed out / switched accounts) while the CLI session was open.","commonSituations":"Long-lived CLI session after cookie expiry; user logged out of Google in the automation Chrome profile; Google invalidated the session server-side (password change, security event); using a profile that was never logged in.","solutions":["Re-authenticate: open the attached Chrome profile, sign in to NotebookLM/Google, then retry the command.","Run `opencli notebooklm open <notebook>` to refresh the session and confirm the page shows the logged-in app.","Check the correct Chrome profile is attached (one that actually holds a valid Google session).","Handle AuthRequiredError in calling code to trigger an interactive login flow before retrying RPC calls."],"exampleFix":"// before: retrying RPC blindly on failure\nconst res = await callNotebooklmRpc(page, auth, method, body);\n// after: catch auth errors and re-authenticate first\nlet res;\ntry {\n  res = await callNotebooklmRpc(page, auth, method, body);\n} catch (e) {\n  if (e instanceof AuthRequiredError) {\n    await reauthenticateNotebooklm(page);\n    res = await callNotebooklmRpc(page, auth, method, body);\n  } else throw e;\n}","handlingStrategy":"try-catch","validationCode":"// check session validity before expensive RPC work\nconst state = await getNotebooklmPageState(page);\nif (state.kind === null || /\\/login/.test(new URL(page.url()).pathname)) {\n  await reauthenticateNotebooklm(page);\n}","typeGuard":null,"tryCatchPattern":"try {\n  const res = await callNotebooklmRpc(page, auth, method, body);\n} catch (e) {\n  if (e instanceof AuthRequiredError && e.message.includes('redirected to the login page')) {\n    await promptGoogleLogin(page); // re-auth in attached Chrome, then retry once\n  } else throw e;\n}","preventionTips":["Re-authenticate periodically in long-running sessions; cookies expire.","Never sign out of Google in the automation Chrome profile while jobs run.","Handle AuthRequiredError centrally with an interactive re-login flow.","Keep the attached Chrome profile dedicated to automation and permanently logged in."],"tags":["authentication","session-expired","redirect","notebooklm"],"backgroundTag":"session-expired-redirect-to-login","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}