{"record":{"id":"c2cb2ecd21b7d8b2","repo":"jackwener/OpenCLI","slug":"notebooklm-rpc-response-redirected-outside-the-act","errorCode":null,"errorMessage":"NotebookLM RPC response redirected outside the active trusted endpoint","messagePattern":"NotebookLM RPC response redirected outside the active trusted endpoint","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/notebooklm/rpc.js","lineNumber":249,"sourceCode":"        `&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}\n","sourceCodeStart":231,"sourceCodeEnd":265,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/notebooklm/rpc.js#L231-L265","documentation":"After the login-redirect check, callNotebooklmRpc validates that response.finalUrl still resolves to the trusted origin with the exact NOTEBOOKLM_RPC_PATH. If the final URL is missing, on another origin, or another path, the response came from somewhere other than the trusted endpoint, so the body cannot be trusted and this CommandExecutionError is thrown. Unlike the login check, this indicates a non-login redirect or an unusable finalUrl.","triggerScenarios":"A redirect chain ends on a non-login page of another origin (SSO loop, consent page on accounts.google.com, proxy block page); finalUrl is absent because the envelope was malformed; the RPC path changed in a frontend update so the final path never equals NOTEBOOKLM_RPC_PATH.","commonSituations":"Google consent/terms interstitial intercepting the request; enterprise proxy redirecting to an auth gateway domain; corrupted response envelope from the in-page bridge; NotebookLM deploying a versioned RPC path.","solutions":["Open the attached Chrome page manually, clear any consent/SSO interstitial, and retry.","Exclude the NotebookLM domain from proxy/SSL interception or disable the VPN and retry.","Log response.finalUrl to see where the redirect chain ends and address that hop specifically.","If NOTEBOOKLM_RPC_PATH changed, update the constant/adapter to the new endpoint path."],"exampleFix":"// before\nconst finalUrl = parseTrustedNotebooklmUrl(response.finalUrl);\n// after: log the offending URL to diagnose redirects\nconst finalUrl = parseTrustedNotebooklmUrl(response.finalUrl);\nif (!finalUrl || finalUrl.origin !== auth.origin) {\n  console.error('RPC ended at unexpected URL:', response.finalUrl);\n}","handlingStrategy":"validation","validationCode":"const finalUrl = parseTrustedNotebooklmUrl(response.finalUrl);\nif (!finalUrl || finalUrl.origin !== auth.origin || finalUrl.pathname !== NOTEBOOKLM_RPC_PATH) {\n  console.error('RPC redirect chain ended at:', response.finalUrl);\n  throw new Error('Untrusted final URL — clear SSO/consent interstitials and proxy redirects first.');\n}","typeGuard":null,"tryCatchPattern":"try {\n  const res = await callNotebooklmRpc(page, auth, method, body);\n} catch (e) {\n  if (e instanceof CommandExecutionError && e.message.includes('redirected outside the active trusted endpoint')) {\n    // inspect response.finalUrl (log it), clear the interstitial/proxy page, retry\n  } else throw e;\n}","preventionTips":["Clear any Google consent/terms interstitials in the automation profile ahead of time.","Exclude notebooklm.google.com (and accounts.google.com) from proxy/SSL interception.","Log finalUrl on every failure to map redirect behavior in your environment.","Update the adapter when NotebookLM changes its RPC path."],"tags":["rpc","redirect","origin-validation","security","notebooklm"],"backgroundTag":"cross-origin-redirect","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}