CloakHQ/CloakBrowser · error · InvalidOperationException
Element not found while scrolling into view
Error message
Element not found while scrolling into view
What it means
InvalidOperationException thrown when the element's bounding box (via the getBox delegate) returns null at the start of HumanScrollIntoViewAsync. The element to scroll to does not currently exist in the DOM.
Source
Thrown at dotnet/src/CloakBrowser/Human/HumanScroll.cs:114
Func<Task<BoundingBox?>> getBox,
double cursorX, double cursorY,
HumanConfig cfg)
{
var viewport = page.ViewportSize;
if (viewport == null)
// Headed launches default to no_viewport so the page tracks the real OS
// window; ViewportSize is then null. Fall back to the live window
// dimensions so humanize works headed (the stealth-relevant mode).
viewport = await page.GetLiveWindowSizeAsync().ConfigureAwait(false);
if (viewport == null || viewport.Value.Height == 0)
throw new InvalidOperationException("Viewport size not available");
int viewportHeight = viewport.Value.Height;
int viewportWidth = viewport.Value.Width;
var box = await getBox().ConfigureAwait(false);
if (box == null)
throw new InvalidOperationException("Element not found while scrolling into view");
if (IsInViewport(box.Value, viewportHeight, cfg))
return new ScrollResult(box.Value, cursorX, cursorY, false);
// Already fully visible but off-center, with the page pinned at the boundary
// in the needed direction: scrolling can't help, so don't waste the budget.
bool fullyVisible = box.Value.Y >= 0 && box.Value.Y + box.Value.Height <= viewportHeight;
if (fullyVisible)
{
double zoneMid = viewportHeight * (cfg.ScrollTargetZone.Min + cfg.ScrollTargetZone.Max) / 2;
bool needUp = box.Value.Y + box.Value.Height / 2 < zoneMid;
var scroll = await page.GetScrollStateAsync().ConfigureAwait(false);
if (scroll != null && (needUp ? scroll.Value.Y <= 0 : scroll.Value.Y >= scroll.Value.MaxY))
return new ScrollResult(box.Value, cursorX, cursorY, false);
}
// Move cursor into scroll area.
double scrollAreaX = Math.Round(viewportWidth * HumanRandom.Rand(0.3, 0.7));View on GitHub (pinned to d6bad5de26)
Solutions
- Wait for the element (WaitForSelectorAsync, state Attached or Visible) before scrolling
- Fix the selector; verify it matches with a quick query
- For virtualized lists, scroll the container first so the row is rendered
- Retry after navigation settles if a click just caused a page change
Example fix
// before
await page.HumanScrollIntoViewAsync("#footer");
// after
await page.WaitForSelectorAsync("#footer");
await page.HumanScrollIntoViewAsync("#footer"); Defensive patterns
Strategy: try-catch
Validate before calling
await page.WaitForSelectorAsync(selector, new() { State = WaitForSelectorState.Attached }); Try / catch
catch (InvalidOperationException e) when (e.Message.Contains("not found while scrolling")) { await page.WaitForSelectorAsync(selector); retry once; } Prevention
- Wait for attachment before scroll-into-view
- Use stable selectors that survive re-renders
- For virtualized lists scroll the container first
When it happens
Trigger: Calling humanized scroll APIs with a selector that matches no attached element, or where the element is detached between the caller's own wait and the internal getBox evaluation.
Common situations: Selector typos, elements removed by React/Vue re-renders, lists virtualized so the row isn't in the DOM yet, or scrolling immediately after a click that triggers navigation.
Related errors
- Pro binary unavailable: ${e}. Your license is valid but the
- Humanized DOM read requires an active isolated world
- Element not found while scrolling into view
- ElementNotAttachedError: {sourceSelector}
- ElementNotAttachedError: {targetSelector}
AI-assisted analysis of CloakHQ/CloakBrowser@d6bad5de26 (2026-08-28).
Data as JSON: /api/errors/513d752fc9619461.
Report an issue: GitHub.