grafana/k6 · error

parsing click options

Error message

parsing click options: %w

What it means

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.

Solutions

  1. Make 'position' an object with numeric x/y: { position: { x: 10, y: 20 } }.
  2. Make 'modifiers' an array of strings: { modifiers: ['Shift', 'Control'] }.
  3. If options come from JSON.parse or a config file, coerce coordinates with Number() and validate modifiers items are strings before the click.
  4. Use the element's natural click point by omitting 'position'.

Example fix

// before
await page.click('#btn', { position: 'center', modifiers: 'Shift' });

// after
await page.click('#btn', { position: { x: 100, y: 50 }, modifiers: ['Shift'] });
Defensive patterns

Strategy: validation

Validate before calling

function clickOpts(o = {}) {
  const { position, modifiers } = o;
  if (position != null && (typeof position !== 'object' || typeof position.x !== 'number' || typeof position.y !== 'number')) throw new Error('position must be { x: number, y: number }');
  if (modifiers != null && (!Array.isArray(modifiers) || !modifiers.every(m => typeof m === 'string'))) throw new Error('modifiers must be string[]');
  return o;
}
await page.click('#btn', clickOpts(cfg.click));

Type guard

function isClickOptions(o) {
  if (o == null) return true;
  if (typeof o !== 'object') return false;
  const p = o.position;
  if (p != null && (typeof p !== 'object' || typeof p.x !== 'number' || typeof p.y !== 'number')) return false;
  const m = o.modifiers;
  if (m != null && (!Array.isArray(m) || !m.every(x => typeof x === 'string'))) return false;
  return true;
}

Try / catch

try { await page.click(sel, opts); } catch (e) { if (/parsing click options/.test(e.message)) { /* recheck position/modifiers types */ } throw e; }

Prevention

When it happens

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

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

Related errors


AI-assisted analysis of grafana/k6@01ffac6f24 (2026-08-18). Data as JSON: /api/errors/302bc110acf8112c. Report an issue: GitHub.

Appendix: source

Thrown at internal/js/modules/k6/browser/browser/mapping.go:45

	var (
		rt  = vu.Runtime()
		obj = rt.NewObject()
	)
	for k, v := range m {
		if err := obj.Set(k, rt.ToValue(v)); err != nil {
			k6common.Throw(rt, k6ext.BrowserError(fmt.Errorf("mapping: %w", err)))
		}
	}

	return obj
}

func parseFrameClickOptions(
	ctx context.Context, opts sobek.Value, defaultTimeout time.Duration,
) (*common.FrameClickOptions, error) {
	copts := common.NewFrameClickOptions(defaultTimeout)
	if err := copts.Parse(ctx, opts); err != nil {
		return nil, fmt.Errorf("parsing click options: %w", err)
	}
	return copts, nil
}

func ConvertSelectOptionValues(rt *sobek.Runtime, values sobek.Value) ([]any, error) {
	if k6common.IsNullish(values) {
		return nil, nil
	}

	var (
		opts []any
		t    = values.Export()
	)
	switch values.ExportType().Kind() {
	case reflect.Slice:
		var sl []any
		if err := rt.ExportTo(values, &sl); err != nil {
			return nil, fmt.Errorf("options: expected array, got %T", values)

View on GitHub (pinned to 01ffac6f24)