{"record":{"id":"100e946c6efaf963","repo":"grafana/k6","slug":"node-has-0-width","errorCode":null,"errorMessage":"node has 0 width","messagePattern":"node has 0 width","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/screenshotter.go","lineNumber":307,"sourceCode":") (buf []byte, err error) {\n\tformat := opts.Format\n\tviewportSize, err := s.originalViewportSize(h.frame.page)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"getting original viewport size: %w\", err)\n\t}\n\toriginalSize := h.frame.page.emulatedSize\n\n\terr = h.waitAndScrollIntoViewIfNeeded(h.ctx, false, true, opts.Timeout)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"scrolling element into view: %w\", err)\n\t}\n\n\tbbox, err := h.boundingBox()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"node is either not visible or not an HTMLElement: %w\", err)\n\t}\n\tif bbox.Width <= 0 {\n\t\treturn nil, fmt.Errorf(\"node has 0 width\")\n\t}\n\tif bbox.Height <= 0 {\n\t\treturn nil, fmt.Errorf(\"node has 0 height\")\n\t}\n\n\tfitsViewport := bbox.Width <= viewportSize.Width && bbox.Height <= viewportSize.Height\n\tif !fitsViewport { //nolint:nestif\n\t\toverriddenViewportSize := Size{\n\t\t\tWidth:  math.Max(viewportSize.Width, bbox.Width),\n\t\t\tHeight: math.Max(viewportSize.Height, bbox.Height),\n\t\t}.enclosingIntSize()\n\t\tdefer func() {\n\t\t\tif restoreErr := s.restoreViewport(h.frame.page, originalSize); restoreErr != nil {\n\t\t\t\terr = errors.Join(err, fmt.Errorf(\"restoring viewport: %w\", restoreErr))\n\t\t\t}\n\t\t}()\n\t\tif err := h.frame.page.setViewportSize(s.ctx, overriddenViewportSize); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"setting viewport size to %s: %w\",","sourceCodeStart":289,"sourceCodeEnd":325,"githubUrl":"https://github.com/grafana/k6/blob/3fcf5388d78cb382f0c0d42ec556a06bfd1b8dee/internal/js/modules/k6/browser/common/screenshotter.go#L289-L325","documentation":"Hard guard in element screenshots: after computing the element's bounding box, its width is <= 0, so there is nothing to capture. The element exists and has a box, but it renders with zero width (height may be fine). Zero-size captures also crash some Chromium versions, hence the explicit check.","triggerScenarios":"await elementHandle.screenshot() on elements styled with width: 0 (or content collapsed by CSS: absolute positioning off-viewport, flex/grid item shrunk to 0, whitespace stripped), or an element whose content has not laid out yet (fonts/images not loaded).","commonSituations":"Screenshotting skeleton loaders or icons rendered via ::before only (host has 0 width); collapsed flex children; elements measured before web fonts/images expand them; responsive layouts under a narrow emulated viewport.","solutions":["Verify computed width in DevTools; fix the CSS (min-width) or wait for content to expand the element.","Wait for images/fonts: await page.waitForLoadState('networkidle') or wait for a size-bearing child.","If capturing a visual, screenshot the parent container that has non-zero size instead.","Set an explicit width on the element in test setup."],"exampleFix":"// before\nawait page.$('.icon-host').screenshot({ path: 'i.png' }); // host is 0px wide\n\n// after\nawait page.$('.icon-wrapper').screenshot({ path: 'i.png' }); // sized container\n// or CSS: .icon-host { min-width: 32px; }","handlingStrategy":"validation","validationCode":"const box = await handle.boundingBox();\nif (!box || box.width <= 0) throw new Error(`element width is ${box ? box.width : 'unknown'}; not capturable`);","typeGuard":"const hasNonZeroWidth = async (h) => {\n  const b = await h.boundingBox();\n  return !!b && b.width > 0;\n};","tryCatchPattern":null,"preventionTips":["Check getComputedStyle width or boundingBox before capturing.","Set min-width on empty hosts (icon wrappers, spacers).","Screenshot a sized parent container instead of zero-width hosts."],"tags":["k6","browser","screenshot","element-handle","layout"],"backgroundTag":"zero-size-element","analyzedSha":"3fcf5388d78cb382f0c0d42ec556a06bfd1b8dee","analyzedAt":"2026-08-18T03:05:52.393Z","contentChangedAt":"2026-08-18T03:05:52.393Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}