grafana/k6 · error

parsing element tap options

Error message

parsing element tap options: %w

What it means

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.

Solutions

  1. Use an array for modifiers: tap({modifiers: ['Alt', 'Shift']}) or omit it
  2. Express position as numeric {x, y} offsets from the element's top-left corner
  3. Validate dynamically-built option objects before calling tap

Example fix

// before
await handle.tap({ modifiers: 'Shift' });
// after
await handle.tap({ modifiers: ['Shift'] });
Defensive patterns

Strategy: try-catch

Validate before calling

const modsOk = (m) => m == null || (Array.isArray(m) && m.every(x => typeof x === 'string'));
const posOk = (p) => p == null || (typeof p === 'object' && !Array.isArray(p) && Number.isFinite(p.x) && Number.isFinite(p.y));
if (!modsOk(opts?.modifiers) || !posOk(opts?.position)) {
  throw new Error('tap options: modifiers must be string[], position must be {x,y} numbers');
}
await handle.tap(opts);

Type guard

function isTapOptions(v) {
  return v == null || (
    (v.modifiers == null || (Array.isArray(v.modifiers) && v.modifiers.every(m => typeof m === 'string'))) &&
    (v.position == null || (Number.isFinite(v.position?.x) && Number.isFinite(v.position?.y)))
  );
}

Try / catch

try {
  await handle.tap(opts);
} catch (e) {
  if (String(e).includes('parsing element tap options')) {
    opts = { ...opts, modifiers: [opts.modifiers].flat().filter(Boolean), position: undefined };
    await handle.tap(opts);
  } else { throw e; }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of grafana/k6@3fcf5388d7 (2026-09-14). Data as JSON: /api/errors/faa7ee2b11c7cda2. Report an issue: GitHub.

Appendix: source

Thrown at internal/js/modules/k6/browser/browser/element_handle_mapping.go:253

			}), nil
		},
		"setInputFiles": func(files sobek.Value, opts sobek.Value) (*sobek.Promise, error) {
			popts, err := parseElementHandleSetInputFilesOptions(rt, opts, eh.DefaultTimeout())
			if err != nil {
				return nil, fmt.Errorf("parsing setInputFiles options: %w", err)
			}
			var pfiles common.Files
			if err := pfiles.Parse(vu.Context(), files); err != nil {
				return nil, fmt.Errorf("parsing setInputFiles parameter: %w", err)
			}
			return promise(vu, func() (any, error) {
				return nil, eh.SetInputFiles(&pfiles, popts) //nolint:wrapcheck
			}), nil
		},
		"tap": func(opts sobek.Value) (*sobek.Promise, error) {
			popts, err := parseElementHandleTapOptions(rt, opts, eh.Timeout())
			if err != nil {
				return nil, fmt.Errorf("parsing element tap options: %w", err)
			}
			return promise(vu, func() (any, error) {
				return nil, eh.Tap(popts) //nolint:wrapcheck
			}), nil
		},
		"textContent": func() *sobek.Promise {
			return promise(vu, func() (any, error) {
				s, ok, err := eh.TextContent()
				if err != nil {
					return nil, err //nolint:wrapcheck
				}
				if !ok {
					return nil, nil
				}
				return s, nil
			})
		},
		"type": func(text string, opts sobek.Value) (*sobek.Promise, error) {

View on GitHub (pinned to 3fcf5388d7)