grafana/k6 · error

parsing element click options: %w

Error message

parsing element click options: %w

What it means

Thrown synchronously by ElementHandle.click() when its options fail to parse. ElementHandleClickOptions embeds the base-pointer options plus button, clickCount, delay and modifiers; in common/element_handle_options.go only two steps can fail: exporting 'position' to map[string]float64 and exporting 'modifiers' to []string (the latter is first wrapped as 'parsing element handle click option modifiers', then again by this message). The mapping returns (nil, error), so the failure is a synchronous JS exception at call time.

Source

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

				if errors.Is(err, common.ErrElementNotVisible) || errors.Is(err, common.ErrElementNotAttachedToDOM) {
					return nil, nil
				}
				return box, err
			})
		},
		"check": func(opts sobek.Value) (*sobek.Promise, error) {
			popts := common.NewElementHandleSetCheckedOptions(eh.DefaultTimeout())
			if err := popts.Parse(vu.Context(), opts); err != nil {
				return nil, fmt.Errorf("parsing check options: %w", err)
			}
			return promise(vu, func() (any, error) {
				return nil, eh.Check(popts) //nolint:wrapcheck
			}), nil
		},
		"click": func(opts sobek.Value) (*sobek.Promise, error) {
			popts := common.NewElementHandleClickOptions(eh.Timeout())
			if err := popts.Parse(vu.Context(), opts); err != nil {
				return nil, fmt.Errorf("parsing element click options: %w", err)
			}

			return promise(vu, func() (any, error) {
				err := eh.Click(popts)
				return nil, err //nolint:wrapcheck
			}), nil
		},
		"contentFrame": func() *sobek.Promise {
			return promise(vu, func() (any, error) {
				f, err := eh.ContentFrame()
				if err != nil {
					return nil, err //nolint:wrapcheck
				}
				return mapFrame(vu, f), nil
			})
		},
		"dblclick": func(opts sobek.Value) (*sobek.Promise, error) {
			popts := common.NewElementHandleDblclickOptions(eh.DefaultTimeout())

View on GitHub (pinned to 93accf6570)

Solutions

  1. Use { modifiers: ['Alt', 'Shift', 'Control', 'Meta'] } (array of strings) and { position: { x: 10, y: 10 } } with numeric x/y
  2. Fix the source producing strings: Number(x), Number(y), and split(' ') for modifiers
  3. Validate the options object with a type guard before calling click
  4. Catch synchronously with try/catch around the call, since no promise is returned on failure

Example fix

// before
await el.click({ modifiers: 'Shift', position: [10, 10] });

// after
await el.click({ modifiers: ['Shift'], position: { x: 10, y: 10 } });
Defensive patterns

Strategy: type-guard

Validate before calling

if (opts) {
  if (opts.position !== undefined &&
      (typeof opts.position !== 'object' || Array.isArray(opts.position) ||
       !Number.isFinite(Number(opts.position.x)) || !Number.isFinite(Number(opts.position.y)))) {
    throw new Error('click(): position must be { x: number, y: number }');
  }
  if (opts.modifiers !== undefined &&
      !(Array.isArray(opts.modifiers) && opts.modifiers.every(m => typeof m === 'string'))) {
    throw new Error('click(): modifiers must be an array of strings');
  }
}

Type guard

function isClickOpts(o) {
  if (o == null) return true;
  const posOk = o.position === undefined ||
    (typeof o.position === 'object' && !Array.isArray(o.position) &&
     Number.isFinite(Number(o.position.x)) && Number.isFinite(Number(o.position.y)));
  const modOk = o.modifiers === undefined ||
    (Array.isArray(o.modifiers) && o.modifiers.every(m => typeof m === 'string'));
  return posOk && modOk;
}

Try / catch

try {
  await el.click(opts);
} catch (e) {
  if (/parsing element click options/.test(String(e.message))) {
    console.log(`fix click options: ${e.message}`);
  } else throw e;
}

Prevention

When it happens

Trigger: el.click({ position: 'topLeft' }) or { position: { x: '5' } } (non-numeric coordinates), el.click({ modifiers: 'Shift' }) (string instead of array), or { modifiers: ['Shift', 2] } (non-string array element). button/clickCount/delay/timeout are lenient coercions and never fail; unknown option keys are ignored.

Common situations: Playwright-to-k6 script ports that pass modifiers as a comma-separated string, or position taken from outer-chain property files where values arrive as strings. Also occurs when a shared options object is reused across page.mouse and element APIs with incompatible shapes.

Related errors


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