{"record":{"id":"1dbbe356fba23e98","repo":"CloakHQ/CloakBrowser","slug":"viewport-size-not-available-1dbbe3","errorCode":null,"errorMessage":"Viewport size not available","messagePattern":"Viewport size not available","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"js/src/human/scroll.ts","lineNumber":95,"sourceCode":"export async function humanScrollIntoView<T extends ElementBounds>(\n  page: Page,\n  raw: RawMouse,\n  getBox: () => Promise<T | null>,\n  cursorX: number,\n  cursorY: number,\n  cfg: HumanConfig,\n): Promise<{ box: T; cursorX: number; cursorY: number; didScroll: boolean }> {\n  let viewport = page.viewportSize();\n  if (!viewport) {\n    const world = getWorld(page);\n    if (!world) throw new StealthWorldUnavailableError();\n    try {\n      viewport = await world.evaluate(VIEWPORT_JS);\n    } catch {\n      throw new StealthEvaluationError('<viewport>');\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, didScroll: false };\n  }\n\n  const fullyVisible = box.y >= 0 && box.y + box.height <= viewport.height;\n  if (fullyVisible) {\n    const zoneMid = viewport.height * (cfg.scroll_target_zone[0] + cfg.scroll_target_zone[1]) / 2;\n    const needUp = box.y + box.height / 2 < zoneMid;\n    const { y, maxY } = await readScrollState(page);\n    if (needUp ? y <= 0 : y >= maxY) {\n      return { box, cursorX, cursorY, didScroll: false };\n    }\n  }\n","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/CloakHQ/CloakBrowser/blob/d6bad5de261bedf025280ace1d14e800aee13923/js/src/human/scroll.ts#L77-L113","documentation":"After resolving the viewport (either from Playwright or the isolated world), humanScrollIntoView requires a truthy object with a positive height. If both sources fail to provide usable dimensions, this generic Error is thrown because subsequent visibility math is impossible. It is a final sanity check, not an element error.","triggerScenarios":"page.viewportSize() returns a zero-height/empty object (or null) and the world fallback also returns an unusable viewport — e.g. a window reduced to zero height, a stubbed/mocked viewportSize in tests, or an embedded/webview context reporting 0.","commonSituations":"Headful windows minimized or sized to zero height; running under xvfb with a broken screen geometry; mocked Page objects in unit tests returning {width:0,height:0}; kiosk/webview embeds with no real viewport.","solutions":["Ensure the browser window has a real size: launch with explicit viewport, args like --window-size=1280,800, or a properly configured xvfb display (1920x1080x24).","If you mock Page in tests, make viewportSize() return realistic dimensions or skip humanized paths in unit tests.","Check that nothing (window manager, CI runner) minimizes the window during the run.","Fall back to non-humanized scrollIntoViewIfNeeded when viewport detection is unreliable in your environment."],"exampleFix":"# before (CI)\nxvfb-run -a --server-args=\"-screen 0 0x0x16\" npm test  # zero-height screen\n\n# after\nxvfb-run -a --server-args=\"-screen 0 1920x1080x24\" npm test","handlingStrategy":"validation","validationCode":"const vp = page.viewportSize();\nif (!vp || !vp.height) throw new Error('Set a real viewport or fix the display size');\nawait scrollToElement(page, raw, selector);","typeGuard":"function hasRealViewport(page: Page): boolean {\n  const vp = page.viewportSize();\n  return !!vp && vp.height > 0;\n}","tryCatchPattern":"try {\n  await scrollToElement(page, raw, selector);\n} catch (e) {\n  if (e instanceof Error && e.message === 'Viewport size not available') {\n    await page.setViewportSize({ width: 1280, height: 720 });\n    await scrollToElement(page, raw, selector);\n  } else throw e;\n}","preventionTips":["Launch with explicit viewport or --window-size in headful runs.","Use a correctly sized xvfb screen in CI (1920x1080x24).","If you mock Page, return realistic viewportSize() values."],"tags":["playwright","viewport","headful","ci","xvfb"],"backgroundTag":"viewport-size-unavailable","analyzedSha":"d6bad5de261bedf025280ace1d14e800aee13923","analyzedAt":"2026-08-28T14:13:12.918Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}