{"record":{"id":"a30c3d37010b7db6","repo":"CloakHQ/CloakBrowser","slug":"element-not-found-while-scrolling-into-view-a30c3d","errorCode":null,"errorMessage":"Element not found while scrolling into view","messagePattern":"Element not found while scrolling into view","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"js/src/human/scroll.ts","lineNumber":98,"sourceCode":"  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\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);","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/CloakHQ/CloakBrowser/blob/d6bad5de261bedf025280ace1d14e800aee13923/js/src/human/scroll.ts#L80-L116","documentation":"Inside humanScrollIntoView, getBox() resolves the element's bounding box (via the isolated-world snapshot). If it returns null at the initial lookup stage, the element could not be found/measured at all, so scrolling cannot proceed. This fires before any scrolling happens — it's the 'element doesn't exist (or has no box) at action time' case.","triggerScenarios":"Calling a humanized click/press or scrollToElement on a selector whose element is detached, display:none/hidden (zero, no layout box), inside a collapsed container, or when the snapshot resolves to nothing because the element hasn't rendered yet.","commonSituations":"Acting before an element is actually rendered (SPA hydration, lazy list virtualization, hidden tabs/accordions); element re-rendered between query and action; selectors matching only in a different frame; display:none until a CSS class toggles.","solutions":["Wait for the element to be actionable first: await page.locator(sel).waitFor({ state: 'visible' }) or use non-humanized scrollIntoViewIfNeeded to force reveal before the human action.","Make the container visible (open the accordion/tab/dropdown) before acting on its children.","If the element is in an iframe, switch page context to that frame — the snapshot only searches the main world's document.","Tighten the selector so it matches the visible instance (e.g. add .first() or a visibility-scoped CSS class)."],"exampleFix":"// before\nawait humanClick(page, 'text=Accept Cookies'); // cookie banner not rendered yet\n\n// after\nawait page.locator('text=Accept Cookies').waitFor({ state: 'visible' });\nawait humanClick(page, 'text=Accept Cookies');","handlingStrategy":"validation","validationCode":"const loc = page.locator(selector).first();\nawait loc.waitFor({ state: 'visible' });\nawait humanClick(page, selector); // element now has a layout box","typeGuard":"async function elementHasBox(page: Page, selector: string): Promise<boolean> {\n  try { return (await page.locator(selector).first().boundingBox()) !== null; }\n  catch { return false; }\n}","tryCatchPattern":"try {\n  await humanClick(page, selector);\n} catch (e) {\n  if (e instanceof Error && e.message === 'Element not found while scrolling into view') {\n    await page.locator(selector).first().waitFor({ state: 'visible' });\n    await humanClick(page, selector);\n  } else throw e;\n}","preventionTips":["Always waitFor({ state: 'visible' }) before humanized actions.","Open containing accordions/tabs/dropdowns before targeting hidden children.","Frame-switch first — the snapshot doesn't cross iframe boundaries."],"tags":["playwright","element-not-found","visibility","rendering","humanize"],"backgroundTag":"element-not-visible","analyzedSha":"d6bad5de261bedf025280ace1d14e800aee13923","analyzedAt":"2026-08-28T14:13:12.918Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}