grafana/k6 · error
parsing mouse up options
Error message
parsing mouse up options: %w
What it means
Thrown by mouse.up(options) when parseMouseDownUpOptions fails — the same parser as mouse.down (browser/mouse_mapping.go:124-145). It accepts 'button' (string) and 'clickCount' (integer); a non-integer clickCount or non-object options value aborts the release before the CDP input event is sent, leaving a pressed button un-released for that call.
Solutions
- Pass an integer: page.mouse().up({ clickCount: 1 }) or no options.
- Normalize once and share the normalized object between down and up.
- Coerce at the boundary: const count = Number(raw); if (!Number.isInteger(count)) throw ...
- Keep the up options structurally identical to the down options you used.
Example fix
// before
await page.mouse().down();
await page.mouse().move(100, 100);
await page.mouse().up({ clickCount: cfg.clicks }); // "1"
// after
const count = Number(cfg.clicks) || 1;
await page.mouse().down();
await page.mouse().move(100, 100);
await page.mouse().up({ clickCount: count }); Defensive patterns
Strategy: validation
Validate before calling
const count = raw == null ? undefined : Number(raw);
if (count != null && !Number.isInteger(count)) throw new Error(`clickCount must be an integer, got ${raw}`);
await page.mouse().down({ clickCount: count });
await page.mouse().up({ clickCount: count }); Type guard
function isDownUpOptions(o) {
if (o == null) return true;
if (typeof o !== 'object') return false;
return (o.clickCount == null || Number.isInteger(o.clickCount)) && (o.button == null || typeof o.button === 'string');
} Try / catch
try { await page.mouse().up(opts); } catch (e) { if (/parsing mouse up options|clickCount must be an integer/.test(e.message)) { await page.mouse().up({ clickCount: parseInt(opts.clickCount, 10) }); } else throw e; } Prevention
- Normalize clickCount once and reuse the same value for down and up.
- Coerce counts from data sources with Number() and an is-integer guard.
- Keep press/release sequences in one helper so options cannot drift apart.
When it happens
Trigger: page.mouse().up({ clickCount: '1' }) or { clickCount: 1.5 } in a press-move-release drag sequence; sharing one options object between down and up calls where the count was coerced to string upstream.
Common situations: Drag-and-drop helper functions that take options from callers; count values round-tripped through JSON; mismatches where down() succeeded with an integer but up() received the string variant of the same config.
Related errors
- parsing mouse click options
- parsing mouse double click options
- parsing mouse down options
- parsing mouse move options
- clickCount must be an integer, got
AI-assisted analysis of grafana/k6@01ffac6f24 (2026-08-18).
Data as JSON: /api/errors/e2769843cfb23683.
Report an issue: GitHub.
Appendix: source
Thrown at internal/js/modules/k6/browser/browser/mouse_mapping.go:46
return nil, fmt.Errorf("parsing mouse double click options: %w", err)
}
return promise(vu, func() (any, error) {
return nil, m.DblClick(x, y, popts) //nolint:wrapcheck
}), nil
},
"down": func(opts sobek.Value) (*sobek.Promise, error) {
popts, err := parseMouseDownUpOptions(rt, opts)
if err != nil {
return nil, fmt.Errorf("parsing mouse down options: %w", err)
}
return promise(vu, func() (any, error) {
return nil, m.Down(popts) //nolint:wrapcheck
}), nil
},
"up": func(opts sobek.Value) (*sobek.Promise, error) {
popts, err := parseMouseDownUpOptions(rt, opts)
if err != nil {
return nil, fmt.Errorf("parsing mouse up options: %w", err)
}
return promise(vu, func() (any, error) {
return nil, m.Up(popts) //nolint:wrapcheck
}), nil
},
"move": func(x float64, y float64, opts sobek.Value) (*sobek.Promise, error) {
popts, err := parseMouseMoveOptions(rt, opts)
if err != nil {
return nil, fmt.Errorf("parsing mouse move options: %w", err)
}
return promise(vu, func() (any, error) {
return nil, m.Move(x, y, popts) //nolint:wrapcheck
}), nil
},
}
}
// parseMouseClickOptions parses the mouse click options from a Sobek value.View on GitHub (pinned to 01ffac6f24)