grafana/k6 · error
parsing locator bounding box options
Error message
parsing locator bounding box options: %w
What it means
Thrown while parsing the options object of locator.boundingBox(options) (browser/locator_mapping.go:36). It wraps FrameBaseOptions.Parse, which reads strict and timeout with coercing conversions and has no failing branch in current k6 — the wrap is defensive. Note that hidden/detached elements do NOT error here: the mapping deliberately resolves to null for ErrElementNotVisible/ErrElementNotAttachedToDOM to match Playwright.
Solutions
- Pass a plain object { timeout: <number> } or nothing at all
- Null-check the resolved value instead of relying on an error for hidden elements
- Coerce dynamic timeout values with Number()
- Upgrade k6 if a plain options object triggers this
Example fix
// before
const box = await locator.boundingBox({ timeout: __ENV.TIMEOUT });
// after
const box = await locator.boundingBox({ timeout: Number(__ENV.TIMEOUT) });
if (!box) throw new Error('element not visible'); Defensive patterns
Strategy: validation
Validate before calling
const o = (opts == null) ? undefined : { ...(opts.timeout !== undefined && { timeout: Number(opts.timeout) }) };
const box = await locator.boundingBox(o);
if (box === null) { /* element hidden or detached — handle, do not expect a throw */ } Type guard
function isBoundingBoxOptions(o) {
return o == null || (typeof o === 'object' && !Array.isArray(o) &&
(o.timeout === undefined || typeof o.timeout === 'number'));
} Try / catch
try { const box = await locator.boundingBox(o); } catch (e) { if (!String(e.message).includes('parsing locator bounding box options')) throw e; } Prevention
- Null-check the resolved value; hidden elements resolve to null instead of throwing
- Pass only { timeout } — boundingBox has no other meaningful options
- Coerce external timeout values with Number()
When it happens
Trigger: Exotic options values that sobek cannot traverse (Symbol, throwing getters); older k6 builds with stricter parsing. Ordinary wrong types like { timeout: '5000' } are coerced, not rejected.
Common situations: Assuming boundingBox() throws when an element is missing (it returns null — check the resolved value instead); passing option objects assembled from JSON with string timeouts on older k6.
Related errors
- parsing check options
- parsing clear options
- parsing double click options
- parsing set checked options
- evaluate requires a page function
AI-assisted analysis of grafana/k6@8d06114777 (2026-09-14).
Data as JSON: /api/errors/605b7e9ff400ed30.
Report an issue: GitHub.
Appendix: source
Thrown at internal/js/modules/k6/browser/browser/locator_mapping.go:37
return mapping{
"all": func() *sobek.Promise {
return promise(vu, func() (any, error) {
all, err := lo.All()
if err != nil {
return nil, err
}
res := make([]mapping, len(all))
for i, el := range all {
res[i] = mapLocator(vu, el)
}
return res, nil
})
},
"boundingBox": func(opts sobek.Value) (*sobek.Promise, error) {
popts := common.NewFrameBaseOptions(lo.Timeout())
if err := parseFrameBaseOptions(popts, rt, opts); err != nil {
return nil, fmt.Errorf("parsing locator bounding box options: %w", err)
}
return promise(vu, func() (any, error) {
box, err := lo.BoundingBox(popts)
// We want to avoid errors when an element is not visible or detached and instead
// opt to return a nil rectangle -- this matches Playwright's behaviour.
if errors.Is(err, common.ErrElementNotVisible) || errors.Is(err, common.ErrElementNotAttachedToDOM) {
return nil, nil
}
return box, err
}), nil
},
"clear": func(opts sobek.Value) (*sobek.Promise, error) {
copts, err := parseFrameFillOptions(rt, opts, lo.Timeout())
if err != nil {
return nil, fmt.Errorf("parsing clear options: %w", err)
}
return promise(vu, func() (any, error) {
return nil, lo.Clear(copts) //nolint:wrapcheckView on GitHub (pinned to 8d06114777)