jackwener/OpenCLI · error · CommandExecutionError
NotebookLM page-state probe returned inconsistent URL and ho
Error message
NotebookLM page-state probe returned inconsistent URL and hostname fields
What it means
After parsing the probe URL, getNotebooklmPageState cross-checks that parsed.hostname equals the separately reported raw.hostname field; a mismatch throws this CommandExecutionError. This consistency check catches probe data where url and hostname disagree — evidence the probe output was assembled incorrectly, intercepted, or spoofed, so the library refuses to trust it for URL classification.
Source
Thrown at clis/notebooklm/utils.js:681
const notebookCount = Array.from(document.querySelectorAll('a[href*="/notebook/"]'))
.map(node => node instanceof HTMLAnchorElement ? node.href : '')
.filter(Boolean)
.reduce((count, href, index, list) => list.indexOf(href) === index ? count + 1 : count, 0);
return { url, title, hostname, kind, notebookId, loginRequired, notebookCount, path };
})()`, 'page-state probe');
if (!isPlainObject(raw) || typeof raw.url !== 'string' || typeof raw.title !== 'string' || typeof raw.hostname !== 'string' || typeof raw.kind !== 'string' || typeof raw.notebookId !== 'string' || typeof raw.loginRequired !== 'boolean' || typeof raw.notebookCount !== 'number' || !Number.isFinite(raw.notebookCount)) {
throw new CommandExecutionError('NotebookLM page-state probe returned malformed Browser Bridge data');
}
let parsed;
try {
parsed = new URL(raw.url);
}
catch {
throw new CommandExecutionError('NotebookLM page-state probe returned an invalid URL');
}
if (parsed.hostname !== raw.hostname) {
throw new CommandExecutionError('NotebookLM page-state probe returned inconsistent URL and hostname fields');
}
const trusted = parseTrustedNotebooklmUrl(parsed.href);
const kind = trusted ? classifyNotebooklmPage(trusted.href) : 'unknown';
const notebookId = kind === 'notebook' ? parseNotebooklmIdFromUrl(trusted.href) : '';
const loginPath = Boolean(trusted && (trusted.pathname === '/login' || trusted.pathname.startsWith('/login/')));
const state = {
url: raw.url,
title: normalizeNotebooklmTitle(raw?.title, 'NotebookLM'),
hostname: raw.hostname,
kind,
notebookId,
loginRequired: loginPath || raw.loginRequired,
notebookCount: Math.max(0, raw.notebookCount),
};
// Notebook pages can still contain "sign in" or login-related text fragments
// even when the active Google session is valid. Prefer the real page tokens
// as the stronger auth signal before declaring the session unauthenticated.
if (isNotebooklmHost(state.hostname) && state.loginRequired && !loginPath) {View on GitHub (pinned to 49907e53dc)
Solutions
- Retry the probe after navigation settles (wait for load/idle) — races between reads are the usual cause
- Reload the NotebookLM page and re-run getNotebooklmPageState
- Disable browser extensions/proxies that rewrite location and retry
- Update the library so url and hostname are captured atomically from the parsed URL rather than separately
- Manually confirm the final URL in the browser to check for unexpected redirects
Example fix
// before: two independent reads in probe
return { url: window.location.href, hostname: window.location.hostname, ... };
// after: derive both from one value
const url = window.location.href;
return { url, hostname: new URL(url).hostname, ... }; Defensive patterns
Strategy: validation
Validate before calling
function hostnameMatches(state) {
try { return new URL(state.url).hostname === state.hostname; }
catch { return false; }
}
// after obtaining state, before trusting it:
if (!hostnameMatches(state)) {
await page.reload();
// re-fetch state
} Type guard
function hasConsistentHost(v) {
if (typeof v?.url !== 'string' || typeof v?.hostname !== 'string') return false;
try { return new URL(v.url).hostname === v.hostname; } catch { return false; }
} Try / catch
try {
const state = await getNotebooklmPageState(page);
} catch (e) {
if (!/inconsistent URL and hostname/.test(e.message)) throw e;
await page.waitForLoadState?.('load') ?? await page.wait(2); // let navigation settle
const state = await getNotebooklmPageState(page);
} Prevention
- Capture url and hostname atomically (derive both from one parsed URL) if customizing the probe
- Avoid probing mid-redirect or during login flows
- Wait for navigation to complete before reading page state
- Disable extensions/security tooling that rewrites location fields
- Treat mismatches as a signal to reload and re-probe, not to proceed with partial data
When it happens
Trigger: getNotebooklmPageState when the probe's hostname field differs from the hostname of raw.url — e.g. a redirect happened between the two reads, an extension modified one of them, or the probe script was altered/failed partially so stale or wrong values were captured.
Common situations: Mid-navigation race where location changed between field reads; security tooling or extensions rewriting location fields; a modified/custom probe returning inconsistent data; unusual redirects between google.com subdomains during login flows.
Related errors
- NotebookLM page-state probe returned an invalid URL
- NotebookLM page-state probe returned malformed Browser Bridg
- 1688 item expects an offer URL or offer ID
- Invalid 1688 store URL
- Invalid 1688 URL
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/49cc50dd5e77c9ac.
Report an issue: GitHub.