grafana/k6 · error
parsing is in viewport options
Error message
parsing is in viewport options: %w
What it means
Thrown synchronously when the options argument to locator.isInViewport() fails to parse. The mapping (locator_mapping.go:173-177) creates common.FrameIsInViewportOptions and wraps Parse failures as "parsing is in viewport options: %w". Parse (frame_options.go:449-462) runs FrameBaseOptions.Parse for strict/timeout and then reads an optional "ratio" via ToFloat; the coercing accessors do not fail on ordinary wrong types, so the wrapped error comes from sobek raising during property access (throwing getter, Proxy trap, or throwing toPrimitive during the ratio/timeout coercion).
Solutions
- Pass a plain literal: locator.isInViewport({ ratio: 0.5, timeout: 3000 })
- Compute ratio beforehand and guard divide-by-zero before the call
- Keep options free of Proxies and accessor properties
- try/catch the call for a controlled failure message
Example fix
// before
const opts = { get ratio() { return visible / total; } }; // throws when total === 0
await locator.isInViewport(opts);
// after
if (total === 0) throw new Error('cannot compute viewport ratio');
await locator.isInViewport({ ratio: visible / total }); Defensive patterns
Strategy: validation
Validate before calling
function assertViewportOptions(opts) {
if (opts == null) return;
if (typeof opts !== 'object') throw new TypeError('isInViewport options must be an object');
if (opts.ratio !== undefined && !Number.isFinite(opts.ratio))
throw new TypeError(`ratio must be a number, got ${typeof opts.ratio}`);
if (opts.timeout !== undefined && !Number.isFinite(opts.timeout))
throw new TypeError(`timeout must be a number, got ${typeof opts.timeout}`);
}
assertViewportOptions(opts);
const ratio = await locator.isInViewport(opts); Type guard
function isViewportOptions(o) {
return o == null || (typeof o === 'object' &&
(o.ratio === undefined || Number.isFinite(o.ratio)) &&
(o.timeout === undefined || Number.isFinite(o.timeout)));
} Try / catch
try { await locator.isInViewport(opts); } catch (e) { if (String(e).includes('parsing is in viewport options')) throw new Error(`bad isInViewport options: ${JSON.stringify(opts)}`); throw e; } Prevention
- Compute ratio before the call and guard divide-by-zero
- Pass ratio as a plain number between 0 and 1
- Avoid getters that throw on option objects
When it happens
Trigger: opts.ratio implemented as a getter that throws; a Proxy around options with raising get/ownKeys traps; a ratio or timeout value whose valueOf/Symbol.toPrimitive raises during ToFloat/ToInteger.
Common situations: Passing a ratio computed from a helper that throws on division by zero inside a getter; tracing Proxies; k6 scripts migrated from Playwright where isInViewport returns a ratio and callers pass computed thresholds as accessors.
Related errors
- parsing fill options
- parsing focus options
- parsing get attribute options
- parsing hover options
- parsing inner HTML options
AI-assisted analysis of grafana/k6@8d06114777 (2026-09-14).
Data as JSON: /api/errors/7e261bfcce9583d5.
Report an issue: GitHub.
Appendix: source
Thrown at internal/js/modules/k6/browser/browser/locator_mapping.go:176
return nil, fmt.Errorf("parsing is enabled options: %w", err)
}
return promise(vu, func() (any, error) {
return lo.IsEnabled(copts) //nolint:wrapcheck
}), nil
},
"isDisabled": func(opts sobek.Value) (*sobek.Promise, error) {
copts, err := parseFrameIsDisabledOptions(rt, opts, lo.Timeout())
if err != nil {
return nil, fmt.Errorf("parsing is disabled options: %w", err)
}
return promise(vu, func() (any, error) {
return lo.IsDisabled(copts) //nolint:wrapcheck
}), nil
},
"isInViewport": func(opts sobek.Value) (*sobek.Promise, error) {
copts, err := parseFrameIsInViewportOptions(rt, opts, lo.Timeout())
if err != nil {
return nil, fmt.Errorf("parsing is in viewport options: %w", err)
}
return promise(vu, func() (any, error) {
return lo.IsInViewport(copts) //nolint:wrapcheck
}), nil
},
"isVisible": func() *sobek.Promise {
return promise(vu, func() (any, error) {
return lo.IsVisible() //nolint:wrapcheck
})
},
"isHidden": func() *sobek.Promise {
return promise(vu, func() (any, error) {
return lo.IsHidden() //nolint:wrapcheck
})
},
"fill": func(value string, opts sobek.Value) (*sobek.Promise, error) {
copts, err := parseFrameFillOptions(rt, opts, lo.Timeout())
if err != nil {View on GitHub (pinned to 8d06114777)