grafana/k6 · error

evaluating scroll offset: %w

Error message

evaluating scroll offset: %w

What it means

Near the end of elementHandle.screenshot(), the code evaluates `() => ({x: window.scrollX, y: window.scrollY})` on the element to translate the viewport-relative bounding box into document coordinates for the CDP clip. This evaluate call failed (wrapped verbatim).

Source

Thrown at internal/js/modules/k6/browser/common/screenshotter.go:324

		err = h.waitAndScrollIntoViewIfNeeded(h.ctx, false, true, opts.Timeout)
		if err != nil {
			return nil, fmt.Errorf("scrolling element into view: %w", err)
		}
		bbox, err = h.boundingBox()
		if err != nil {
			return nil, fmt.Errorf("node is either not visible or not an HTMLElement: %w", err)
		}
		if bbox.Width <= 0 {
			return nil, fmt.Errorf("node has 0 width")
		}
		if bbox.Height <= 0 {
			return nil, fmt.Errorf("node has 0 height")
		}
	}

	scrollOffset, err := h.Evaluate(`() => { return {x: window.scrollX, y: window.scrollY};}`)
	if err != nil {
		return nil, fmt.Errorf("evaluating scroll offset: %w", err)
	}

	var returnVal Position
	if err := convert(scrollOffset, &returnVal); err != nil {
		return nil, fmt.Errorf("unpacking scroll offset: %w", err)
	}

	documentRect := bbox
	documentRect.X += returnVal.X
	documentRect.Y += returnVal.Y

	buf, err := s.screenshot(
		h.frame.page.session,
		documentRect.enclosingIntRect(),
		nil, // viewportRect
		format,
		opts.OmitBackground,
		opts.Quality,

View on GitHub (pinned to 93accf6570)

Solutions

  1. Suppress navigation during capture (block redirects, avoid auto-refreshing pages) or capture immediately after load settles.
  2. Await everything before screenshot and keep the page open until it resolves.
  3. Increase the browser timeout option if the whole flow is just slow.
  4. Retry once — transient context-destroyed errors are common.

Example fix

// before
await page.$('#report').then(el => el.screenshot({ path: 'r.png' })); // page auto-refreshes mid-capture

// after
await page.route('**/refresh*', r => r.abort()); // or wait past the refresh
await page.goto(url); await page.waitForLoadState('load');
await (await page.$('#report')).screenshot({ path: 'r.png' });
Defensive patterns

Strategy: try-catch

Validate before calling

await page.waitForLoadState('load'); // and block auto-refresh: await page.route('**/refresh*', r => r.abort());

Try / catch

try { await el.screenshot({ path: 'e.png' }); }
catch (e) {
  if (/evaluating scroll offset|Execution context was destroyed/i.test(String(e))) {
    await sleep(500); await el.screenshot({ path: 'e.png' }); // one retry
  } else throw e;
}

Prevention

When it happens

Trigger: Execution context destroyed by a navigation or DOM-ready reload between boundingBox and evaluate; page/target closed; renderer crash; k6 context cancelled (timeout/teardown) mid-screenshot.

Common situations: Pages with auto-refresh/meta-refresh or SPA route changes during capture; screenshot racing page.close(); slow pages where the element screenshot exceeds the browser-timeout budget.

Related errors


AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15). Data as JSON: /api/errors/9dfb7c27ca2afc34. Report an issue: GitHub.