CloakHQ/CloakBrowser · error · Error
Viewport size not available
Error message
Viewport size not available
What it means
humanScrollIntoView could not obtain a usable viewport: page.viewport() returned null and the in-page window.innerWidth/innerHeight evaluation returned a falsy height. Scrolling math needs viewport height, so it aborts.
Source
Thrown at js/src/human-puppeteer/scroll.ts:105
*/
export async function humanScrollIntoView(
page: Page,
raw: RawMouse,
getBox: () => Promise<ElementBounds | null>,
cursorX: number,
cursorY: number,
cfg: HumanConfig,
): Promise<{ box: ElementBounds; cursorX: number; cursorY: number }> {
// Headed launches default to null defaultViewport so the page tracks the real
// OS window; page.viewport() is then null. Fall back to the live window
// dimensions so humanize works headed (the stealth-relevant mode).
let viewport = page.viewport();
if (!viewport) {
viewport = await page.evaluate(
() => ({ width: window.innerWidth, height: window.innerHeight }),
);
}
if (!viewport || !viewport.height) throw new Error('Viewport size not available');
let box = await getBox();
if (!box) throw new Error('Element not found while scrolling into view');
if (isInViewport(box, viewport.height, cfg)) {
return { box, cursorX, cursorY };
}
// Move cursor into scroll area
const scrollAreaX = Math.round(viewport.width * rand(0.3, 0.7));
const scrollAreaY = Math.round(viewport.height * rand(0.3, 0.7));
await humanMove(raw, cursorX, cursorY, scrollAreaX, scrollAreaY, cfg);
cursorX = scrollAreaX;
cursorY = scrollAreaY;
await sleep(randRange(cfg.scroll_pre_move_delay));
// Calculate scroll distance
const targetY = viewport.height * rand(cfg.scroll_target_zone[0], cfg.scroll_target_zone[1]);View on GitHub (pinned to d6bad5de26)
Solutions
- Ensure the page is fully open and not navigating before calling humanScrollIntoView
- Set an explicit viewport when creating the page/browser context (page.setViewport or defaultViewport)
- Await pending navigations (page.waitForNavigation / networkidle) before scrolling
- Guard with a page.isClosed() check and skip/retry the scroll
Example fix
// before
await humanScrollIntoView(page, selector);
// after
if (page.isClosed()) throw new Error('page closed');
await page.setViewport({ width: 1280, height: 800 });
await humanScrollIntoView(page, selector); Defensive patterns
Strategy: validation
Validate before calling
async function ensureViewport(page: Page): Promise<void> {
if (page.isClosed()) throw new Error('page closed');
if (!page.viewport()) await page.setViewport({ width: 1280, height: 800 });
} Type guard
function isViewportUnavailable(e: unknown): e is Error {
return e instanceof Error && e.message === 'Viewport size not available';
} Try / catch
try { await humanScrollIntoView(page, sel); }
catch (e) { if (isViewportUnavailable(e)) { await page.setViewport({width:1280,height:800}); await humanScrollIntoView(page, sel); } else throw e; } Prevention
- Always set an explicit viewport at context/page creation
- Never call scroll helpers on a closed or navigating page
- Await document readiness before humanized interactions
When it happens
Trigger: Calling humanScrollIntoView on a page that is closing/closed, a page in an odd headless mode where viewport is unset and window dimensions are 0, or when page.evaluate fails silently returning undefined.
Common situations: Browser context torn down concurrently (navigation/close race), zero-sized headless viewport configuration, or calling scroll helpers after page.close() began.
Related errors
- CLOAKBROWSER_BINARY_PATH set to '${localOverride}' but file
- Viewport size not available
- Invalid browser version pin. Use a full numeric Chromium ver
- Unsupported platform: ${platform} ${arch}. Supported: ${supp
- CloakBrowser — Pre-built binaries are currently only availab
AI-assisted analysis of CloakHQ/CloakBrowser@d6bad5de26 (2026-08-28).
Data as JSON: /api/errors/1f15449f8a30247f.
Report an issue: GitHub.