grafana/k6 · error

dispatching element event %q: %w

Error message

dispatching element event %q: %w

What it means

DispatchEvent wraps the injected dispatchEvent evaluation, run as a retrying action under the default element timeout. Failures include eval errors (element detached, context destroyed), non-serializable eventInit payloads, and timeouts.

Source

Thrown at internal/js/modules/k6/browser/common/element_handle.go:898

		return fmt.Errorf("double clicking on element: %w", err)
	}

	applySlowMo(h.ctx)

	return nil
}

// DispatchEvent dispatches a DOM event to the element.
func (h *ElementHandle) DispatchEvent(typ string, eventInit any) error {
	dispatchEvent := func(apiCtx context.Context, handle *ElementHandle) (any, error) {
		return handle.dispatchEvent(apiCtx, typ, eventInit)
	}
	opts := NewElementHandleBaseOptions(h.DefaultTimeout())
	dispatchEventAction := h.newAction(
		[]string{}, dispatchEvent, opts.Force, withRetry, opts.NoWaitAfter, opts.Timeout,
	)
	if _, err := call(h.ctx, dispatchEventAction, opts.Timeout); err != nil {
		return fmt.Errorf("dispatching element event %q: %w", typ, err)
	}

	applySlowMo(h.ctx)

	return nil
}

// Fill types the given value into the element.
func (h *ElementHandle) Fill(value string, opts *ElementHandleBaseOptions) error {
	fill := func(apiCtx context.Context, handle *ElementHandle) (any, error) {
		return nil, handle.fill(apiCtx, value)
	}
	fillAction := h.newAction(
		[]string{"visible", "enabled", "editable"},
		fill, opts.Force, withRetry, opts.NoWaitAfter, opts.Timeout,
	)
	if _, err := call(h.ctx, fillAction, opts.Timeout); err != nil {
		return fmt.Errorf("filling element: %w", err)

View on GitHub (pinned to 93accf6570)

Solutions

  1. Ensure eventInit is a plain serializable object (strings, numbers, booleans, arrays, nested objects)
  2. Re-locate the element right before dispatching
  3. Use a valid event type name (e.g. 'click', 'submit', 'custom-event')
  4. Increase the timeout if the page is slow

Example fix

// before
await handle.dispatchEvent('search', { query: () => 'k6' }); // dispatching element event

// after
await handle.dispatchEvent('search', { detail: { query: 'k6' } });
Defensive patterns

Strategy: try-catch

Validate before calling

// eventInit must be plain serializable data
function isPlainSerializable(v) {
  if (v === null) return true;
  const t = typeof v;
  if (['string', 'number', 'boolean'].includes(t)) return true;
  if (t !== 'object') return false;
  return Object.values(v).every(isPlainSerializable);
}
if (!isPlainSerializable(eventInit)) throw new Error('eventInit not serializable');

Try / catch

try {
  await handle.dispatchEvent('click', { bubbles: true });
} catch (e) {
  if (String(e).includes('dispatching element event')) {
    await (await page.$(sel)).dispatchEvent('click', { bubbles: true });
  } else { throw e; }
}

Prevention

When it happens

Trigger: handle.dispatchEvent('click', eventInit) where eventInit contains non-JSON-serializable values, the element detaches before dispatch, the execution context dies, or the action exceeds the timeout.

Common situations: Dispatching custom events on dynamically removed nodes; passing functions/DOM nodes/class instances in eventInit; wrong event type strings; slow pages exceeding the default timeout.

Related errors


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