jackwener/OpenCLI · error · AuthRequiredError
NotebookLM RPC returned auth error (${errorCode})
Error message
NotebookLM RPC returned auth error (${errorCode}) What it means
extractNotebooklmRpcResult walks the batchexecute response frames looking for error entries. When an error frame carries numeric code 401 or 403 (from item[2] or item[5]), it throws AuthRequiredError for NOTEBOOKLM_DOMAIN — the server explicitly rejected the request as unauthenticated or forbidden. This is the library's signal that the Chrome session's Google credentials are not valid for this RPC.
Source
Thrown at clis/notebooklm/rpc.js:158
return chunks;
}
export function extractNotebooklmRpcResult(rawBody, rpcId) {
const chunks = parseNotebooklmChunkedResponse(rawBody);
for (const chunk of chunks) {
if (!Array.isArray(chunk))
continue;
const items = Array.isArray(chunk[0]) ? chunk : [chunk];
for (const item of items) {
if (!Array.isArray(item) || item.length < 1)
continue;
if (item[0] === 'er') {
const errorCode = typeof item[2] === 'number'
? item[2]
: typeof item[5] === 'number'
? item[5]
: null;
if (errorCode === 401 || errorCode === 403) {
throw new AuthRequiredError(NOTEBOOKLM_DOMAIN, `NotebookLM RPC returned auth error (${errorCode})`);
}
throw new CliError('NOTEBOOKLM_RPC', `NotebookLM RPC failed${errorCode ? ` (code=${errorCode})` : ''}`, 'Retry from an already logged-in NotebookLM session, or inspect the raw response with debug logging.');
}
if (item[0] === 'wrb.fr' && item[1] === rpcId) {
const payload = item[2];
if (typeof payload === 'string') {
try {
return JSON.parse(payload);
}
catch {
throw new CliError('NOTEBOOKLM_RPC_SCHEMA', `NotebookLM RPC ${rpcId} returned malformed JSON`, 'Retry from the NotebookLM page; the internal RPC response shape may have changed.');
}
}
return payload;
}
}
}
throw new CliError('NOTEBOOKLM_RPC_SCHEMA', `NotebookLM RPC ${rpcId} returned no matching response frame`, 'Retry from the NotebookLM page; the internal RPC response shape may have changed.');View on GitHub (pinned to 49907e53dc)
Solutions
- Re-login to Google in the linked Chrome profile and reopen the NotebookLM notebook, then retry
- Select the correct --authuser profile that actually has access to the notebook
- Verify you can open the same notebook manually in that Chrome window
- If 403 persists while logged in, check VPN/proxy IP blocks or notebook sharing permissions
Example fix
// before (retrying with dead cookies) await callNotebooklmRpc(page, rpcId, payload); // after (refresh auth context first) const auth = await probeNotebooklmPageAuth(page); // throws AuthRequiredError early if session dead await callNotebooklmRpc(page, rpcId, payload);
Defensive patterns
Strategy: try-catch
Validate before calling
// cheap pre-flight: confirm the session can load the notebook page
const res = await fetchNotebooklmInPage(page, notebookUrl);
if (!res.ok || res.status === 401 || res.status === 403) {
throw new Error('Google session lacks access; re-login or check notebook permissions before RPC');
} Type guard
function isAuthRequiredError(e) {
return e instanceof Error && /auth error \((401|403)\)/.test(e.message);
} Try / catch
try {
const data = await callNotebooklmRpc(page, rpcId, payload);
} catch (e) {
if (isAuthRequiredError(e)) {
console.error('Re-login to Google in the linked Chrome profile, reopen the notebook, then retry.');
} else throw e;
} Prevention
- Keep the Chrome Google session fresh; re-login before long workflows
- Verify the profile (--authuser) actually has access to the target notebook
- Avoid VPN/proxy IPs that Google may block with 403
When it happens
Trigger: callNotebooklmRpc sends a batchexecute request with the page's csrf/session tokens and the response contains an error frame with errorCode 401 (session expired/not logged in) or 403 (forbidden — no access to that notebook or region/abuse block).
Common situations: Google session in the linked Chrome profile expired (SAPISID cookies stale); the notebook was shared without the user or was deleted; corporate/VPN egress IP is rate-limited or blocked; wrong authuser profile selected (one with no access).
Related errors
- Gmail ${operation} returned HTTP ${status}
- 未登录或登录已过期,请先在浏览器中登录贝壳找房
- LinkedIn Learning auth failed (HTTP ${result.status ?? ''}).
- MiniMax ${region.host} rejected ${MINIMAX_API_KEY_VAR} (HTTP
- NotebookLM RPC returned auth error (${response.status})
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/d5eba87635260a58.
Report an issue: GitHub.