{"record":{"id":"302bc110acf8112c","repo":"grafana/k6","slug":"parsing-click-options-w","errorCode":null,"errorMessage":"parsing click options: %w","messagePattern":"parsing click options: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/browser/mapping.go","lineNumber":45,"sourceCode":"\tvar (\n\t\trt  = vu.Runtime()\n\t\tobj = rt.NewObject()\n\t)\n\tfor k, v := range m {\n\t\tif err := obj.Set(k, rt.ToValue(v)); err != nil {\n\t\t\tk6common.Throw(rt, k6ext.BrowserError(fmt.Errorf(\"mapping: %w\", err)))\n\t\t}\n\t}\n\n\treturn obj\n}\n\nfunc parseFrameClickOptions(\n\tctx context.Context, opts sobek.Value, defaultTimeout time.Duration,\n) (*common.FrameClickOptions, error) {\n\tcopts := common.NewFrameClickOptions(defaultTimeout)\n\tif err := copts.Parse(ctx, opts); err != nil {\n\t\treturn nil, fmt.Errorf(\"parsing click options: %w\", err)\n\t}\n\treturn copts, nil\n}\n\nfunc ConvertSelectOptionValues(rt *sobek.Runtime, values sobek.Value) ([]any, error) {\n\tif k6common.IsNullish(values) {\n\t\treturn nil, nil\n\t}\n\n\tvar (\n\t\topts []any\n\t\tt    = values.Export()\n\t)\n\tswitch values.ExportType().Kind() {\n\tcase reflect.Slice:\n\t\tvar sl []any\n\t\tif err := rt.ExportTo(values, &sl); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"options: expected array, got %T\", values)","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/grafana/k6/blob/01ffac6f245854c1b8adc6a69857c76a15f90022/internal/js/modules/k6/browser/browser/mapping.go#L27-L63","documentation":"Thrown by the shared click option parser (parseFrameClickOptions in the browser mapping layer) used by Page/Frame/Locator click variants. FrameClickOptions.Parse delegates to embedded parsers; failures come from ElementHandleBasePointerOptions.Parse rejecting a 'position' that is not an object of numbers (common/element_handle_options.go:188-192) or 'modifiers' not being an array of strings (element_handle_options.go:307-310). The click never reaches the browser when this fires.","triggerScenarios":"page.click(sel, { position: 'center' }) or { position: { x: '10', y: 20 } } (string coordinates fail rt.ExportTo into map[string]float64); { modifiers: 'Shift' } or { modifiers: ['Shift', 3] } instead of an array of strings. Any page.click/frame.click/locator.click call routes through this parser.","commonSituations":"Porting Playwright scripts where position came from a boundingBox() result that was JSON round-tripped (numbers became strings); passing a single modifier string instead of an array; config objects built from parsed JSON where all values are strings.","solutions":["Make 'position' an object with numeric x/y: { position: { x: 10, y: 20 } }.","Make 'modifiers' an array of strings: { modifiers: ['Shift', 'Control'] }.","If options come from JSON.parse or a config file, coerce coordinates with Number() and validate modifiers items are strings before the click.","Use the element's natural click point by omitting 'position'."],"exampleFix":"// before\nawait page.click('#btn', { position: 'center', modifiers: 'Shift' });\n\n// after\nawait page.click('#btn', { position: { x: 100, y: 50 }, modifiers: ['Shift'] });","handlingStrategy":"validation","validationCode":"function clickOpts(o = {}) {\n  const { position, modifiers } = o;\n  if (position != null && (typeof position !== 'object' || typeof position.x !== 'number' || typeof position.y !== 'number')) throw new Error('position must be { x: number, y: number }');\n  if (modifiers != null && (!Array.isArray(modifiers) || !modifiers.every(m => typeof m === 'string'))) throw new Error('modifiers must be string[]');\n  return o;\n}\nawait page.click('#btn', clickOpts(cfg.click));","typeGuard":"function isClickOptions(o) {\n  if (o == null) return true;\n  if (typeof o !== 'object') return false;\n  const p = o.position;\n  if (p != null && (typeof p !== 'object' || typeof p.x !== 'number' || typeof p.y !== 'number')) return false;\n  const m = o.modifiers;\n  if (m != null && (!Array.isArray(m) || !m.every(x => typeof x === 'string'))) return false;\n  return true;\n}","tryCatchPattern":"try { await page.click(sel, opts); } catch (e) { if (/parsing click options/.test(e.message)) { /* recheck position/modifiers types */ } throw e; }","preventionTips":["Always build position from boundingBox() numbers or explicit numeric literals.","Pass modifiers as an array of strings, never a single string.","When options come from JSON, coerce position coordinates with Number() at load time."],"tags":["k6","browser","click","options-parsing","position"],"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"}