grafana/k6 · error
parsing hover options: %w
Error message
parsing hover options: %w
What it means
The options object passed to frame.hover(selector, opts) failed to parse (frame_mapping.go:221). ElementHandleHoverOptions parses 'position' (must be {x: number, y: number}) and 'modifiers' (must be an array of strings); a value that cannot export to those types throws this error synchronously.
Source
Thrown at internal/js/modules/k6/browser/browser/frame_mapping.go:221
f.Referrer(),
f.NavigationTimeout(),
)
if err := gopts.Parse(vu.Context(), opts); err != nil {
return nil, fmt.Errorf("parsing frame navigation options to %q: %w", url, err)
}
return promise(vu, func() (any, error) {
resp, err := f.Goto(url, gopts)
if err != nil {
return nil, err //nolint:wrapcheck
}
return mapResponse(vu, resp), nil
}), nil
},
"hover": func(selector string, opts sobek.Value) (*sobek.Promise, error) {
popts := common.NewFrameHoverOptions(f.Timeout())
if err := popts.Parse(vu.Context(), opts); err != nil {
return nil, fmt.Errorf("parsing hover options: %w", err)
}
return promise(vu, func() (any, error) {
return nil, f.Hover(selector, popts) //nolint:wrapcheck
}), nil
},
"innerHTML": func(selector string, opts sobek.Value) (*sobek.Promise, error) {
popts := common.NewFrameInnerHTMLOptions(f.Timeout())
if err := popts.Parse(vu.Context(), opts); err != nil {
return nil, fmt.Errorf("parsing inner HTML options: %w", err)
}
return promise(vu, func() (any, error) {
return f.InnerHTML(selector, popts) //nolint:wrapcheck
}), nil
},
"innerText": func(selector string, opts sobek.Value) (*sobek.Promise, error) {
popts := common.NewFrameInnerTextOptions(f.Timeout())
if err := popts.Parse(vu.Context(), opts); err != nil {
return nil, fmt.Errorf("parsing inner text options: %w", err)View on GitHub (pinned to 93accf6570)
Solutions
- Use { position: { x: 10, y: 20 } } and { modifiers: ['Shift'] }
- Coerce JSON-sourced values before calling: position: { x: Number(p.x), y: Number(p.y) }
- Drop position entirely to hover the element center (the default)
Example fix
// before
frame.hover('#menu', { position: 'center' });
// after
frame.hover('#menu', { position: { x: 150, y: 30 } }); Defensive patterns
Strategy: type-guard
Validate before calling
const norm = {
...opts,
...(opts?.modifiers && !Array.isArray(opts.modifiers) ? { modifiers: String(opts.modifiers).split(',') } : {}),
...(opts?.position ? { position: { x: Number(opts.position.x), y: Number(opts.position.y) } } : {}),
}; Type guard
function isHoverOptions(o) {
if (o == null) return true;
const posOk = o.position == null || (typeof o.position === 'object' && !Array.isArray(o.position)
&& Number.isFinite(Number(o.position.x)) && Number.isFinite(Number(o.position.y)));
const modOk = o.modifiers == null || (Array.isArray(o.modifiers) && o.modifiers.every(m => typeof m === 'string'));
return posOk && modOk;
} Try / catch
try {
await frame.hover(sel, norm);
} catch (e) {
if (String(e.message).includes('parsing hover options')) throw new Error(`bad hover opts for ${sel}: ${JSON.stringify(opts)}`);
throw e;
} Prevention
- Omit position to hover the element center; specify {x, y} numbers only
- modifiers must be an array like ['Shift']
- Validate option objects once where they enter the script (config load), not per call
When it happens
Trigger: frame.hover('#el', { position: 'center' }), { position: [10, 10] }, or { modifiers: 'Shift' } (string not array) - the sobek ExportTo fails and gets wrapped as 'parsing hover options:'.
Common situations: Reusing click/dblclick option objects verbatim for hover; JSON-sourced configs where numbers arrive as strings; Playwright ports using tuple positions or CSS-style position keywords.
Related errors
- parsing new frame check options: %w
- parsing double click options: %w
- parsing frame dispatch event options: %w
- parsing fill options: %w
- parsing focus options: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/fa7062b1d024aa8f.
Report an issue: GitHub.