garrytan/gstack · warning · Error
Cannot use forward inside a frame. Run 'frame main' first.
Error message
Cannot use forward inside a frame. Run 'frame main' first.
What it means
Frame-context guard in the forward case at write-commands.ts:166. page.goForward() is a top-level-page operation and is blocked when a subframe context is active (session.getFrame() !== null).
Source
Thrown at browse/src/write-commands.ts:165
if (!url) throw new Error('Usage: browse goto <url>');
// Clear loadedHtml BEFORE navigation — a timeout after the main-frame commit
// must not leave stale content that could resurrect on a later context recreation.
session.clearLoadedHtml();
const normalizedUrl = await validateNavigationUrl(url);
const response = await page.goto(normalizedUrl, { waitUntil: 'domcontentloaded', timeout: 15000 });
const status = response?.status() || 'unknown';
return `Navigated to ${normalizedUrl} (${status})`;
}
case 'back': {
if (inFrame) throw new Error('Cannot use back inside a frame. Run \'frame main\' first.');
session.clearLoadedHtml();
await page.goBack({ waitUntil: 'domcontentloaded', timeout: 15000 });
return `Back → ${page.url()}`;
}
case 'forward': {
if (inFrame) throw new Error('Cannot use forward inside a frame. Run \'frame main\' first.');
session.clearLoadedHtml();
await page.goForward({ waitUntil: 'domcontentloaded', timeout: 15000 });
return `Forward → ${page.url()}`;
}
case 'reload': {
if (inFrame) throw new Error('Cannot use reload inside a frame. Run \'frame main\' first.');
session.clearLoadedHtml();
await page.reload({ waitUntil: 'domcontentloaded', timeout: 15000 });
return `Reloaded ${page.url()}`;
}
case 'load-html': {
if (inFrame) throw new Error('Cannot use load-html inside a frame. Run \'frame main\' first.');
// --from-file <path.json>: read inline HTML from a JSON payload. Used by
// make-pdf to dodge Windows argv size limits on large rendered HTML.
// The JSON shape is { html: string, waitUntil?: "load"|"domcontentloaded"|"networkidle" }.View on GitHub (pinned to 94993f7401)
Solutions
- Run 'frame main' before 'forward'
- Keep all top-level navigation outside of frame-scoped blocks
- Check session.getFrame() === null before calling
Example fix
// before
await handleWriteCommand('forward', [], session, bm) // in frame → throws
// after
await handleWriteCommand('frame', ['main'], session, bm)
await handleWriteCommand('forward', [], session, bm) Defensive patterns
Strategy: validation
Validate before calling
function canNavigate(session: { getFrame(): unknown }): boolean {
return session.getFrame() === null
} Type guard
function isMainFrameSession(s: { getFrame(): unknown }): boolean {
return s.getFrame() === null
} Prevention
- Run 'frame main' before 'forward'
- Sequence navigations before frame entry
- Guard on getFrame() === null
When it happens
Trigger: Running 'forward' while a frame context is active.
Common situations: Continuing an automated session after entering a frame, without returning to the main frame.
Related errors
- Cannot use goto inside a frame. Run 'frame main' first.
- Cannot use back inside a frame. Run 'frame main' first.
- Cannot use reload inside a frame. Run 'frame main' first.
- Cannot use load-html inside a frame. Run 'frame main' first.
- Usage: browse goto <url>
AI-assisted analysis of garrytan/gstack@94993f7401 (2026-08-12).
Data as JSON: /api/errors/a53505edd54cb649.
Report an issue: GitHub.