grafana/k6 · error
node has 0 height
Error message
node has 0 height
What it means
Sibling of the zero-width guard: the element's bounding box height is <= 0 at screenshot time, so the capture is refused. Width may be positive, but a zero-height element (collapsed row, empty block before content loads) yields no pixels.
Solutions
- Wait for the content that gives the element height (chart rendered, items loaded) before capturing.
- Give the container a min-height in test CSS or app CSS.
- Re-check with a computed-style assertion in page.evaluate(() => getComputedStyle(el).height).
- Screenshot a parent wrapper with non-zero height instead.
Example fix
// before
const c = page.$('#chart');
await c.waitFor(); // attached but 0px tall
await c.screenshot({ path: 'c.png' });
// after
const c = page.$('#chart');
await c.waitFor();
await page.waitForFunction(() => document.querySelector('#chart').clientHeight > 0);
await c.screenshot({ path: 'c.png' }); Defensive patterns
Strategy: validation
Validate before calling
await page.waitForFunction((sel) =>
document.querySelector(sel)?.clientHeight > 0, selector);
await handle.screenshot({ path: 'e.png' }); Type guard
const hasNonZeroHeight = async (h) => {
const b = await h.boundingBox();
return !!b && b.height > 0;
}; Prevention
- Wait for chart libraries/async content to size their containers before capture.
- Give containers a min-height in test CSS.
- Verify clientHeight > 0 with waitForFunction for dynamic content.
When it happens
Trigger: await elementHandle.screenshot() on elements with height: 0 / collapsed (empty container before async content renders, display collapsed by CSS grid auto rows, element whose only content is absolutely positioned and removed from flow).
Common situations: Screenshotting a chart container before the chart library initializes it; empty list/table bodies; accordions measured while closed; elements whose height comes only from floated/absolute children that have not rendered.
Related errors
- node has 0 width
- getting original viewport size
- node is either not visible or not an HTMLElement
- scrolling element into view
- capturing screenshot
AI-assisted analysis of grafana/k6@3fcf5388d7 (2026-09-20).
Data as JSON: /api/errors/df64217bbc30724e.
Report an issue: GitHub.
Appendix: source
Thrown at internal/js/modules/k6/browser/common/screenshotter.go:310
if err != nil {
return nil, fmt.Errorf("getting original viewport size: %w", err)
}
originalSize := h.frame.page.emulatedSize
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")
}
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()
defer func() {
if restoreErr := s.restoreViewport(h.frame.page, originalSize); restoreErr != nil {
err = errors.Join(err, fmt.Errorf("restoring viewport: %w", restoreErr))
}
}()
if err := h.frame.page.setViewportSize(s.ctx, overriddenViewportSize); err != nil {
return nil, fmt.Errorf("setting viewport size to %s: %w",
overriddenViewportSize, err)
}
err = h.waitAndScrollIntoViewIfNeeded(h.ctx, false, true, opts.Timeout)View on GitHub (pinned to 3fcf5388d7)