grafana/k6 · error
setting viewport size to %s: %w
Error message
setting viewport size to %s: %w
What it means
When an element is larger than the viewport, elementHandle.screenshot() first grows the viewport to max(viewport, boundingBox) via setViewportSize (Emulation.setDeviceMetricsOverride). This error wraps that CDP call failing, and includes the attempted size.
Source
Thrown at internal/js/modules/k6/browser/common/screenshotter.go:303
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")
}
var overriddenViewportSize *Size
fitsViewport := bbox.Width <= viewportSize.Width && bbox.Height <= viewportSize.Height
if !fitsViewport { //nolint:nestif
overriddenViewportSize = Size{
Width: math.Max(viewportSize.Width, bbox.Width),
Height: math.Max(viewportSize.Height, bbox.Height),
}.enclosingIntSize()
if err := h.frame.page.setViewportSize(overriddenViewportSize); err != nil {
return nil, fmt.Errorf("setting viewport size to %s: %w",
overriddenViewportSize, err)
}
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")
}
}
View on GitHub (pinned to 93accf6570)
Solutions
- Stabilize the page before capture (await goto, waitForLoadState, no concurrent close).
- Retry the element screenshot once — transient emulation errors often clear.
- Set an initial viewport large enough to contain the element so no resize is needed.
- If sizes are extreme, capture with page.screenshot({fullPage:true}) or clip instead of element screenshot.
Example fix
// before
await page.$('.wide-table').then(el => el.screenshot({ path: 't.png' })); // element >> viewport, racing load
// after
const p = await browser.newPage({ viewport: { width: 1920, height: 2400 } });
await p.goto(url); await p.waitForLoadState('load');
await (await p.$('.wide-table')).screenshot({ path: 't.png' }); Defensive patterns
Strategy: try-catch
Validate before calling
const bb = await locator.boundingBox(); const fits = bb && bb.width <= 1280 && bb.height <= 720; // compare with your viewport; resize upfront if not
Try / catch
try { await el.screenshot({ path: 'e.png' }); }
catch (e) { if (String(e).includes('setting viewport size')) { /* wait for idle page, retry once */ } else throw e; } Prevention
- Open pages with a viewport large enough for the target element.
- Avoid resizing captures while navigation is pending.
- Keep the page open until the screenshot resolves.
When it happens
Trigger: elementHandle.screenshot() on an element wider/taller than the viewport while the page is closing/navigating, the renderer is gone, or device-metrics emulation is in a bad state; also context cancellation during k6 teardown.
Common situations: Screenshotting full-width tables/long sections racing navigation; browser crash under load; oversized elements (huge data grids) hitting chrome's device-metrics limits.
Related errors
- parsing element handle screenshot options: %w
- getting viewport dimensions: %w
- setting screenshot background transparency: %w
- capturing screenshot: %w
- resetting screenshot background color: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/d054ba42f81c8e2f.
Report an issue: GitHub.