{"record":{"id":"a9ac8ae39bc02a24","repo":"grafana/k6","slug":"w-w","errorCode":null,"errorMessage":"%w: %w","messagePattern":"%w: %w","errorType":"exception","errorClass":"ErrElementNotVisible","httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/element_handle.go","lineNumber":825,"sourceCode":"\t\t\tparts[i] = part.Body\n\t\t} else {\n\t\t\tparts[i] = part.Name + \"=\" + part.Body\n\t\t}\n\t}\n\n\treturn strings.Join(parts, \" >> \")\n}\n\n// AsElement returns this element handle.\nfunc (h *ElementHandle) AsElement() *ElementHandle {\n\treturn h\n}\n\n// BoundingBox returns this element's bounding box.\nfunc (h *ElementHandle) BoundingBox() (*Rect, error) {\n\tbbox, err := h.boundingBox()\n\tif err != nil && strings.Contains(err.Error(), \"Could not compute box model\") {\n\t\treturn nil, fmt.Errorf(\"%w: %w\", ErrElementNotVisible, err)\n\t}\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"getting bounding box: %w\", err)\n\t}\n\treturn bbox, nil\n}\n\n// Click scrolls element into view and clicks in the center of the element\n// TODO: look into making more robust using retries\n// (see: https://github.com/microsoft/playwright/blob/master/src/server/dom.ts#L298)\nfunc (h *ElementHandle) Click(opts *ElementHandleClickOptions) error {\n\tclick := h.newPointerAction(\n\t\tfunc(apiCtx context.Context, handle *ElementHandle, p *Position) (any, error) {\n\t\t\treturn nil, handle.click(p, opts.ToMouseClickOptions())\n\t\t},\n\t\t&opts.ElementHandleBasePointerOptions,\n\t)\n\tif _, err := call(h.ctx, click, opts.Timeout); err != nil {","sourceCodeStart":807,"sourceCodeEnd":843,"githubUrl":"https://github.com/grafana/k6/blob/3fcf5388d78cb382f0c0d42ec556a06bfd1b8dee/internal/js/modules/k6/browser/common/element_handle.go#L807-L843","documentation":"BoundingBox() wraps its lower-level call: when the underlying error text contains 'Could not compute box model' (Chrome's response for elements with no layout box), k6 re-wraps it with ErrElementNotVisible using Go's multi-%w, so errors.Is(err, ErrElementNotVisible) matches. The element exists but has no computable geometry.","triggerScenarios":"Calling BoundingBox(), click(), screenshot-of-element, or any geometry-dependent API on an element with display:none, visibility:hidden collapse, or detached-from-layout state; the CDP GetBoxModel call at element_handle.go:67 succeeds/fails with the 'Could not compute box model' message and gets dual-wrapped here.","commonSituations":"Elements in hidden tabs, collapsed accordions, or before CSS/animation layout completes; shadow-DOM content not yet rendered; checking geometry of elements removed by SPA re-render between query and call.","solutions":["Wait for visibility before geometry-dependent calls: await el.waitFor({ state: 'visible' })","Reveal the container (open the tab/accordion) before measuring","Treat ErrElementNotVisible explicitly in Go code with errors.Is to distinguish it from session errors","Re-query the element after SPA re-renders rather than caching handles"],"exampleFix":"// before\nconst box = await el.boundingBox();\n\n// after\nawait el.waitFor({ state: 'visible' });\nconst box = await el.boundingBox();","handlingStrategy":"validation","validationCode":"if (!(await el.isVisible())) {\n  await el.waitFor({ state: 'visible', timeout: 10_000 });\n}\nconst box = await el.boundingBox();","typeGuard":null,"tryCatchPattern":"try {\n  const box = await el.boundingBox();\n} catch (e) {\n  if (/element is not visible/.test(String(e))) {\n    await el.waitFor({ state: 'visible' });\n    const box = await el.boundingBox();\n  } else throw e;\n}","preventionTips":["Wait for visible state before any geometry call (boundingBox, click, screenshot)","Reveal hidden containers (tabs, accordions) before measuring their children","In Go extensions, branch on errors.Is(err, ErrElementNotVisible) instead of string matching"],"tags":["browser","bounding-box","element-not-visible","errors-is"],"backgroundTag":"element-not-visible","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"}