{"record":{"id":"1f15449f8a30247f","repo":"CloakHQ/CloakBrowser","slug":"viewport-size-not-available","errorCode":null,"errorMessage":"Viewport size not available","messagePattern":"Viewport size not available","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"js/src/human-puppeteer/scroll.ts","lineNumber":105,"sourceCode":" */\nexport async function humanScrollIntoView(\n  page: Page,\n  raw: RawMouse,\n  getBox: () => Promise<ElementBounds | null>,\n  cursorX: number,\n  cursorY: number,\n  cfg: HumanConfig,\n): Promise<{ box: ElementBounds; cursorX: number; cursorY: number }> {\n  // Headed launches default to null defaultViewport so the page tracks the real\n  // OS window; page.viewport() is then null. Fall back to the live window\n  // dimensions so humanize works headed (the stealth-relevant mode).\n  let viewport = page.viewport();\n  if (!viewport) {\n    viewport = await page.evaluate(\n      () => ({ width: window.innerWidth, height: window.innerHeight }),\n    );\n  }\n  if (!viewport || !viewport.height) throw new Error('Viewport size not available');\n\n  let box = await getBox();\n  if (!box) throw new Error('Element not found while scrolling into view');\n\n  if (isInViewport(box, viewport.height, cfg)) {\n    return { box, cursorX, cursorY };\n  }\n\n  // Move cursor into scroll area\n  const scrollAreaX = Math.round(viewport.width * rand(0.3, 0.7));\n  const scrollAreaY = Math.round(viewport.height * rand(0.3, 0.7));\n  await humanMove(raw, cursorX, cursorY, scrollAreaX, scrollAreaY, cfg);\n  cursorX = scrollAreaX;\n  cursorY = scrollAreaY;\n  await sleep(randRange(cfg.scroll_pre_move_delay));\n\n  // Calculate scroll distance\n  const targetY = viewport.height * rand(cfg.scroll_target_zone[0], cfg.scroll_target_zone[1]);","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/CloakHQ/CloakBrowser/blob/d6bad5de261bedf025280ace1d14e800aee13923/js/src/human-puppeteer/scroll.ts#L87-L123","documentation":"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.","triggerScenarios":"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.","commonSituations":"Browser context torn down concurrently (navigation/close race), zero-sized headless viewport configuration, or calling scroll helpers after page.close() began.","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"],"exampleFix":"// before\nawait humanScrollIntoView(page, selector);\n\n// after\nif (page.isClosed()) throw new Error('page closed');\nawait page.setViewport({ width: 1280, height: 800 });\nawait humanScrollIntoView(page, selector);","handlingStrategy":"validation","validationCode":"async function ensureViewport(page: Page): Promise<void> {\n  if (page.isClosed()) throw new Error('page closed');\n  if (!page.viewport()) await page.setViewport({ width: 1280, height: 800 });\n}","typeGuard":"function isViewportUnavailable(e: unknown): e is Error {\n  return e instanceof Error && e.message === 'Viewport size not available';\n}","tryCatchPattern":"try { await humanScrollIntoView(page, sel); }\ncatch (e) { if (isViewportUnavailable(e)) { await page.setViewport({width:1280,height:800}); await humanScrollIntoView(page, sel); } else throw e; }","preventionTips":["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"],"tags":["puppeteer","viewport","scroll","page-lifecycle"],"backgroundTag":"puppeteer-viewport-unavailable","analyzedSha":"d6bad5de261bedf025280ace1d14e800aee13923","analyzedAt":"2026-08-28T14:13:12.918Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}