{"record":{"id":"50e8bd1840a5d0b5","repo":"grafana/k6","slug":"parsing-mouse-move-options-w","errorCode":null,"errorMessage":"parsing mouse move options: %w","messagePattern":"parsing mouse move options: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/browser/mouse_mapping.go","lineNumber":55,"sourceCode":"\t\t\t\treturn nil, fmt.Errorf(\"parsing mouse down options: %w\", err)\n\t\t\t}\n\t\t\treturn promise(vu, func() (any, error) {\n\t\t\t\treturn nil, m.Down(popts) //nolint:wrapcheck\n\t\t\t}), nil\n\t\t},\n\t\t\"up\": func(opts sobek.Value) (*sobek.Promise, error) {\n\t\t\tpopts, err := parseMouseDownUpOptions(rt, opts)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"parsing mouse up options: %w\", err)\n\t\t\t}\n\t\t\treturn promise(vu, func() (any, error) {\n\t\t\t\treturn nil, m.Up(popts) //nolint:wrapcheck\n\t\t\t}), nil\n\t\t},\n\t\t\"move\": func(x float64, y float64, opts sobek.Value) (*sobek.Promise, error) {\n\t\t\tpopts, err := parseMouseMoveOptions(rt, opts)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"parsing mouse move options: %w\", err)\n\t\t\t}\n\t\t\treturn promise(vu, func() (any, error) {\n\t\t\t\treturn nil, m.Move(x, y, popts) //nolint:wrapcheck\n\t\t\t}), nil\n\t\t},\n\t}\n}\n\n// parseMouseClickOptions parses the mouse click options from a Sobek value.\nfunc parseMouseClickOptions(rt *sobek.Runtime, opts sobek.Value) (*common.MouseClickOptions, error) {\n\tpopts := common.NewMouseClickOptions()\n\tif k6common.IsNullish(opts) {\n\t\treturn popts, nil\n\t}\n\n\tobj := opts.ToObject(rt)\n\tfor _, k := range obj.Keys() {\n\t\tv := obj.Get(k)","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/grafana/k6/blob/01ffac6f245854c1b8adc6a69857c76a15f90022/internal/js/modules/k6/browser/browser/mouse_mapping.go#L37-L73","documentation":"Thrown by mouse.move(x, y, options) when parseMouseMoveOptions fails. The move parser (browser/mouse_mapping.go:148+, following the same manual key loop as the other mouse parsers) reads 'steps' as an integer; a non-integer steps value or a non-object options argument is wrapped with this message before the movement is dispatched.","triggerScenarios":"page.mouse().move(10, 20, { steps: '5' }) or { steps: 2.5 } — steps interpolates intermediate points between the current and target position, so pacing code that computes fractional steps is the usual source; non-object values in the options slot also fail.","commonSituations":"Steps computed from distance/velocity math producing floats; config-driven step counts parsed as strings from env vars; porting drag helpers from Playwright where steps semantics match but typing differs.","solutions":["Pass an integer: { steps: 5 } or omit steps for a single jump.","Round computed steps: { steps: Math.max(1, Math.round(dist / stepSize)) }.","Coerce env/config values with Number() and verify Number.isInteger before the call.","Remember steps < 1 is pointless — clamp to at least 1."],"exampleFix":"// before\nawait page.mouse().move(200, 200, { steps: dist / 40 }); // 4.75\n\n// after\nawait page.mouse().move(200, 200, { steps: Math.max(1, Math.round(dist / 40)) });","handlingStrategy":"validation","validationCode":"const steps = raw == null ? undefined : Math.max(1, Math.round(Number(raw.steps)));\nawait page.mouse().move(x, y, steps ? { steps } : undefined);","typeGuard":"function isMoveOptions(o) {\n  if (o == null) return true;\n  if (typeof o !== 'object') return false;\n  return o.steps == null || Number.isInteger(o.steps);\n}","tryCatchPattern":"try { await page.mouse().move(x, y, { steps }); } catch (e) { if (/parsing mouse move options|steps must be an integer/.test(e.message)) { await page.mouse().move(x, y, { steps: Math.round(steps) }); } else throw e; }","preventionTips":["Pass steps as an integer of at least 1.","Round computed step counts from distance math.","Coerce env/config values with Number() before use."],"tags":["k6","browser","mouse","mouse-move","options-parsing"],"backgroundTag":"invalid-options-argument","analyzedSha":"01ffac6f245854c1b8adc6a69857c76a15f90022","analyzedAt":"2026-08-18T03:05:52.393Z","contentChangedAt":"2026-08-18T03:05:52.393Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}