CloakHQ/CloakBrowser · error · Error
Element lost after scrolling into view
Error message
Element lost after scrolling into view
What it means
humanScrollIntoView performed its smooth scrolling, waited the configured scroll_settle_delay, then re-measured the element with a final getBox(). If that final lookup returns null, the element that existed before scrolling is gone afterward, so its coordinates can't be returned to the caller. This is the post-scroll analogue of a detached/stale element.
Source
Thrown at js/src/human/scroll.ts:179
}
if (Math.random() < cfg.scroll_overshoot_chance) {
const overshootPx = Math.round(randRange(cfg.scroll_overshoot_px)) * direction;
await smoothWheel(raw, overshootPx, cfg);
await sleep(randRange(cfg.scroll_settle_delay));
const corrections = randIntRange([1, 2]);
for (let c = 0; c < corrections; c++) {
const corrDelta = Math.round(rand(40, 80)) * -direction;
await smoothWheel(raw, corrDelta, cfg);
await sleep(rand(100, 250));
}
}
await sleep(randRange(cfg.scroll_settle_delay));
const finalBox = await getBox();
if (!finalBox) throw new Error('Element lost after scrolling into view');
return { box: finalBox, cursorX, cursorY, didScroll: true };
}
export async function scrollToElement(
page: Page,
raw: RawMouse,
selector: string,
cursorX: number,
cursorY: number,
cfg: HumanConfig,
timeout: number = 30000,
): Promise<{ box: SelectorBounds; cursorX: number; cursorY: number; didScroll: boolean }> {
return humanScrollIntoView(
page,
raw,
() => getElementBox(page, selector, timeout),
cursorX,
cursorY,View on GitHub (pinned to d6bad5de26)
Solutions
- Increase cfg.scroll_settle_delay so lazy re-renders complete before the final box lookup.
- Target a stable container ancestor instead of the recycled node (e.g. the list item wrapper that isn't virtualized), then navigate to the child after scrolling.
- Wait for the element to re-stabilize and retry the humanized action (catch this error and re-run once).
- If re-mounting is inherent (virtualization), use locator.scrollIntoViewIfNeeded + a fresh locator resolution for the click instead of the humanized scroll path.
Example fix
// before
const cfg = { ...defaults, scroll_settle_delay: 50 };
await humanClick(page, 'li.item-42', cfg); // node recycled mid-scroll
// after
const cfg = { ...defaults, scroll_settle_delay: 400 };
await page.locator('li.item-42').waitFor({ state: 'attached' });
await humanClick(page, 'li.item-42', cfg); Defensive patterns
Strategy: retry
Validate before calling
const cfg = { ...defaults, scroll_settle_delay: 400 };
await page.locator(selector).waitFor({ state: 'attached' });
await humanClick(page, selector, cfg); Type guard
null
Try / catch
try {
await humanClick(page, selector, cfg);
} catch (e) {
if (e instanceof Error && e.message === 'Element lost after scrolling into view') {
await page.locator(selector).waitFor({ state: 'visible', timeout: 2000 });
await humanClick(page, selector, cfg); // element re-mounted; retry once
} else throw e;
} Prevention
- Raise scroll_settle_delay on pages with lazy/virtualized rendering.
- Target stable container elements instead of virtualized/recycled nodes.
- Scroll with scrollIntoViewIfNeeded and re-resolve the locator before clicking when re-mounts are expected.
When it happens
Trigger: An element that is present initially but removed by the act of scrolling — lazy-loaded lists that virtualize/replace DOM nodes on scroll, infinite feeds that re-render items, overlays that close or re-mount on scroll events, or the page navigating during the settle delay.
Common situations: React/Vue virtualized lists (react-window, virtual-scroller) recycling the target row's DOM node on scroll; lazy images/components re-mounting after scroll triggers an intersection observer; SPA route change fired by a scroll listener; scroll_settle_delay too short so re-render races the final measurement.
Related errors
- Invalid browser version pin. Use a full numeric Chromium ver
- CloakBrowser Pro: license key is invalid or expired (plan=${
- Isolated-world DOM evaluation failed for ${selector}
- Humanized DOM read requires an active isolated world
- Isolated-world DOM evaluation failed for "<scroll-state>"
AI-assisted analysis of CloakHQ/CloakBrowser@d6bad5de26 (2026-08-28).
Data as JSON: /api/errors/f2d169c55b36bf6e.
Report an issue: GitHub.