{"record":{"id":"faa7ee2b11c7cda2","repo":"grafana/k6","slug":"parsing-element-tap-options-w","errorCode":null,"errorMessage":"parsing element tap options: %w","messagePattern":"parsing element tap options: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/browser/element_handle_mapping.go","lineNumber":253,"sourceCode":"\t\t\t}), nil\n\t\t},\n\t\t\"setInputFiles\": func(files sobek.Value, opts sobek.Value) (*sobek.Promise, error) {\n\t\t\tpopts, err := parseElementHandleSetInputFilesOptions(rt, opts, eh.DefaultTimeout())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"parsing setInputFiles options: %w\", err)\n\t\t\t}\n\t\t\tvar pfiles common.Files\n\t\t\tif err := pfiles.Parse(vu.Context(), files); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"parsing setInputFiles parameter: %w\", err)\n\t\t\t}\n\t\t\treturn promise(vu, func() (any, error) {\n\t\t\t\treturn nil, eh.SetInputFiles(&pfiles, popts) //nolint:wrapcheck\n\t\t\t}), nil\n\t\t},\n\t\t\"tap\": func(opts sobek.Value) (*sobek.Promise, error) {\n\t\t\tpopts, err := parseElementHandleTapOptions(rt, opts, eh.Timeout())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"parsing element tap options: %w\", err)\n\t\t\t}\n\t\t\treturn promise(vu, func() (any, error) {\n\t\t\t\treturn nil, eh.Tap(popts) //nolint:wrapcheck\n\t\t\t}), nil\n\t\t},\n\t\t\"textContent\": func() *sobek.Promise {\n\t\t\treturn promise(vu, func() (any, error) {\n\t\t\t\ts, ok, err := eh.TextContent()\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err //nolint:wrapcheck\n\t\t\t\t}\n\t\t\t\tif !ok {\n\t\t\t\t\treturn nil, nil\n\t\t\t\t}\n\t\t\t\treturn s, nil\n\t\t\t})\n\t\t},\n\t\t\"type\": func(text string, opts sobek.Value) (*sobek.Promise, error) {","sourceCodeStart":235,"sourceCodeEnd":271,"githubUrl":"https://github.com/grafana/k6/blob/3fcf5388d78cb382f0c0d42ec556a06bfd1b8dee/internal/js/modules/k6/browser/browser/element_handle_mapping.go#L235-L271","documentation":"Thrown synchronously when ElementHandle.tap cannot parse its options into ElementHandleTapOptions. The parser type-checks two fields via sobek ExportTo: position must export to map[string]float64 and modifiers must export to []string; everything else (force, noWaitAfter, timeout, trial) is coerced and unknown keys are ignored. So the error means position or modifiers has the wrong shape.","triggerScenarios":"tap({modifiers: 'Shift'}) — a string instead of an array; tap({position: {x: '0', y: 0}}) or tap({position: [10, 10]}) — position values not numeric object keys.","commonSituations":"Writing modifiers as a single string (common slip from keyboard API usage); passing CSS-like or array coordinates for position on touch-enabled pages tested via CDP.","solutions":["Use an array for modifiers: tap({modifiers: ['Alt', 'Shift']}) or omit it","Express position as numeric {x, y} offsets from the element's top-left corner","Validate dynamically-built option objects before calling tap"],"exampleFix":"// before\nawait handle.tap({ modifiers: 'Shift' });\n// after\nawait handle.tap({ modifiers: ['Shift'] });","handlingStrategy":"try-catch","validationCode":"const modsOk = (m) => m == null || (Array.isArray(m) && m.every(x => typeof x === 'string'));\nconst posOk = (p) => p == null || (typeof p === 'object' && !Array.isArray(p) && Number.isFinite(p.x) && Number.isFinite(p.y));\nif (!modsOk(opts?.modifiers) || !posOk(opts?.position)) {\n  throw new Error('tap options: modifiers must be string[], position must be {x,y} numbers');\n}\nawait handle.tap(opts);","typeGuard":"function isTapOptions(v) {\n  return v == null || (\n    (v.modifiers == null || (Array.isArray(v.modifiers) && v.modifiers.every(m => typeof m === 'string'))) &&\n    (v.position == null || (Number.isFinite(v.position?.x) && Number.isFinite(v.position?.y)))\n  );\n}","tryCatchPattern":"try {\n  await handle.tap(opts);\n} catch (e) {\n  if (String(e).includes('parsing element tap options')) {\n    opts = { ...opts, modifiers: [opts.modifiers].flat().filter(Boolean), position: undefined };\n    await handle.tap(opts);\n  } else { throw e; }\n}","preventionTips":["Write modifiers as arrays everywhere, even for a single key: ['Shift']","Keep position numeric {x, y}","Centralize tap/click option builders so shapes are validated once"],"tags":["k6","browser","element-handle","tap","modifiers","options"],"backgroundTag":"options-validation-failed","analyzedSha":"3fcf5388d78cb382f0c0d42ec556a06bfd1b8dee","analyzedAt":"2026-09-14T20:10:14.619Z","contentChangedAt":"2026-09-14T20:10:14.619Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}