grafana/k6 · error
capturing screenshot
Error message
capturing screenshot: %w
What it means
The core screenshot failure: the CDP Page.captureScreenshot command (with any accumulated quality/format/clip options) returned an error. Everything before it (background override, layout metrics, clip computation) succeeded; the capture itself failed. The wrapped error carries the CDP reason, most commonly 'target closed' after a renderer crash.
Solutions
- Read the wrapped CDP error: 'target closed'/'session detached' → renderer died or page closed; fix memory/shm (--disable-dev-shm-usage, bigger container) or guard with page.isClosed().
- Retry the screenshot once after a wait — navigation races are often transient.
- For huge full-page captures, cap dimensions by clipping or reduce viewport to avoid renderer OOM.
- Launch Chromium with --disable-gpu / --disable-dev-shm-usage in containers.
- Avoid screenshotting while triggering navigations in the same tick.
Example fix
// before (bare chromium, small shm container)
await page.screenshot({ path: 'big.png', fullPage: true });
// after
const browser = chromium.launch({
args: ['--disable-dev-shm-usage', '--disable-gpu'],
});
await page.screenshot({ path: 'big.png', fullPage: true }); Defensive patterns
Strategy: retry
Validate before calling
if (page.isClosed()) throw new Error('page closed before screenshot');
await page.waitForLoadState('load'); Try / catch
try {
buf = await page.screenshot({ path: 's.png' });
} catch (e) {
if (/capturing screenshot/i.test(String(e)) && !/target closed/i.test(String(e))) {
await page.waitForTimeout(500);
buf = await page.screenshot({ path: 's.png' });
} else throw e; // target closed: renderer/page gone, no point retrying
} Prevention
- Launch Chromium with --disable-dev-shm-usage (and often --disable-gpu) in containers.
- Don't screenshot during navigations or teardown.
- Cap full-page screenshot size to avoid renderer OOM.
- Distinguish retryable capture races from fatal 'target closed' errors before retrying.
When it happens
Trigger: page.screenshot() / elementHandle.screenshot() when the renderer process crashes (OOM), the page navigates away mid-capture, the target is closed by the script or teardown, or Chrome hits an internal error producing the image (e.g. zero-size capture on some GPU-less headless setups).
Common situations: Docker/CI Chrome crashes from small /dev/shm or memory limits on large full-page screenshots; screenshotting during redirect churn; GPU rendering issues in headless containers requiring software rendering flags.
Related errors
- getting layout metrics for screenshot
- resetting screenshot background color
- setting screenshot background transparency
- setting viewport size
- converting result ( of type %t) to size
AI-assisted analysis of grafana/k6@3fcf5388d7 (2026-09-20).
Data as JSON: /api/errors/6427a8d503899270.
Report an issue: GitHub.
Appendix: source
Thrown at internal/js/modules/k6/browser/common/screenshotter.go:243
scale := 1.0
if viewport != nil {
scale = visualViewportScale
}
clip = &cdppage.Viewport{
X: doc.X,
Y: doc.Y,
Width: doc.Width,
Height: doc.Height,
Scale: scale,
}
if clip.Width > 0 && clip.Height > 0 {
capture = capture.WithClip(clip)
}
// Capture screenshot
buf, err = capture.Do(cdp.WithExecutor(s.ctx, sess))
if err != nil {
return nil, fmt.Errorf("capturing screenshot: %w", err)
}
// Save screenshot capture to file
if path != "" {
if err := s.persister.Persist(s.ctx, path, bytes.NewBuffer(buf)); err != nil {
return nil, fmt.Errorf("persisting screenshot: %w", err)
}
}
return buf, nil
}
func getViewPortDimensions(ctx context.Context, sess session, logger *log.Logger) (float64, float64, float64, error) {
visualViewportScale := 1.0
visualViewportPageX, visualViewportPageY := 0.0, 0.0
// Add clip region
//nolint:dogsledView on GitHub (pinned to 3fcf5388d7)