grafana/k6 · error

parsing click options: %w

Error message

parsing click options: %w

What it means

parseFrameClickOptions is the shared helper behind click-style mappings (locator.click, frame.click, page.click — and the same FrameClickOptions type serves dblclick/contextMenu paths), building FrameClickOptions from ElementHandleClickOptions, which embeds the strict pointer parser. The live error path is position: it must export to map[string]float64, so click({ position: ... }) with a string or non-numeric coordinates fails as 'parsing click options: <export error>'. Other keys (button, modifiers handled elsewhere, force, noWaitAfter, trial, timeout, strict) are coerced leniently.

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 93accf6570)

Solutions

  1. Omit position to click the element center, or pass numeric coordinates: click({ position: { x: 50, y: 50 } })
  2. Coerce string coordinates with Number() before the call
  3. Pass timeout inside the options object as a number: { timeout: 5000 }
  4. Keep only supported keys: position, button, modifiers, force, noWaitAfter, trial, strict, timeout

Example fix

// before
await page.locator('#map').click({ position: 'center', timeout: '5s' });

// after
await page.locator('#map').click({ timeout: 5000 }); // center by default
// or
await page.locator('#map').click({ position: { x: 50, y: 50 }, timeout: 5000 });
Defensive patterns

Strategy: validation

Validate before calling

function assertClickOpts(opts) {
  if (opts === null || opts === undefined) return;
  if (typeof opts !== 'object' || Array.isArray(opts)) {
    throw new TypeError('click options must be a plain object');
  }
  if ('position' in opts && opts.position !== undefined) {
    const p = opts.position;
    if (typeof p !== 'object' || p === null || Array.isArray(p) ||
        typeof p.x !== 'number' || typeof p.y !== 'number') {
      throw new TypeError("click position must be { x: number, y: number }; 'center' or string coords are not supported");
    }
  }
  if ('timeout' in opts && typeof opts.timeout !== 'number') {
    throw new TypeError('click timeout must be a number (ms)');
  }
}

Type guard

function isPointerPosition(v) {
  return typeof v === 'object' && v !== null && !Array.isArray(v) &&
    typeof v.x === 'number' && Number.isFinite(v.x) &&
    typeof v.y === 'number' && Number.isFinite(v.y);
}

Try / catch

try {
  await locator.click(opts); // same guard applies to frame.click / page.click
} catch (e) {
  if (/parsing click options/.test(String(e.message))) {
    throw new Error(`Bad click options (check position/timeout types): ${e.message}`);
  }
  throw e;
}

Prevention

When it happens

Trigger: click({ position: 'center' }) — unsupported literal; click({ position: { x: '50', y: '50' } }) — string coordinates; click({ position: [50, 50] }) — array instead of {x, y}; click('50ms') — scalar in the opts slot.

Common situations: Clicking canvas or map elements with coordinates sourced from JSON that arrive as strings; porting Playwright examples that use explicit positions; passing a timeout string positionally like older k6 examples.

Related errors


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