grafana/k6 · error

node has 0 height

Error message

node has 0 height

What it means

Same guard as the width check: elementHandle.screenshot() rejects elements whose bounding box height <= 0 on the first measurement. The element is attached and has a box, but renders with zero height.

Source

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

	viewportSize, originalViewportSize, err := s.originalViewportSize(h.frame.page)
	if err != nil {
		return nil, fmt.Errorf("getting original viewport size: %w", 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")
	}

	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()

View on GitHub (pinned to 93accf6570)

Solutions

  1. Wait for content to size the element: waitForFunction on getBoundingClientRect().height > 0, or wait for the child content's visibility.
  2. Set an explicit height on the wrapper via page.evaluate if you control the page.
  3. Adjust the page viewport so responsive CSS does not collapse the element.
  4. Fall back to page.screenshot({clip}) around the intended area.

Example fix

// before
await page.$('#chart-wrap').then(el => el.screenshot({ path: 'c.png' })); // chart not loaded, height 0

// after
await page.waitForFunction(() => document.querySelector('#chart-wrap').getBoundingClientRect().height > 0);
await (await page.$('#chart-wrap')).screenshot({ path: 'c.png' });
Defensive patterns

Strategy: validation

Validate before calling

const bb = await locator.boundingBox();
if (!bb || bb.height <= 0) throw new Error('element has zero height; wait for content to load');

Type guard

function hasPositiveHeight(bb) { return bb != null && Number.isFinite(bb.height) && bb.height > 0; }

Try / catch

try { await el.screenshot({ path: 'e.png' }); }
catch (e) { if (String(e).includes('node has 0 height')) { /* waitForFunction height>0, retry */ } else throw e; }

Prevention

When it happens

Trigger: Elements collapsed via height:0/overflow:hidden, containers with only absolutely-positioned children, elements whose content (images/fonts) has not loaded so they have no intrinsic height, or elements hidden by responsive CSS at the current viewport width.

Common situations: Capturing chart/iframe wrappers before their content sizes them; hamburger-menu panels at mobile widths; CSS transitions from height:0; media queries collapsing elements at the default 1280x720 viewport.

Related errors


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