grafana/k6 · error

dispatching frame event %q to %q: %w

Error message

dispatching frame event %q to %q: %w

What it means

Frame.DispatchEvent() waits for an element matching the selector to be attached, then dispatches a DOM event (typ) with the given eventInit on it. This error wraps failures of the wait or the dispatch: selector wait timeout, strict-mode ambiguity, eventInit serialization problems, or the element detaching before dispatch.

Source

Thrown at internal/js/modules/k6/browser/common/frame.go:826

	dblclick := func(_ context.Context, eh *ElementHandle, p *Position) (any, error) {
		return nil, eh.dblclick(p, opts.ToMouseClickOptions())
	}
	act := f.newPointerAction(
		selector, DOMElementStateAttached, opts.Strict, dblclick, &opts.ElementHandleBasePointerOptions,
	)
	if _, err := call(f.ctx, act, opts.Timeout); err != nil {
		return errorFromDOMError(err)
	}

	return nil
}

// DispatchEvent dispatches an event for the first element matching the selector.
func (f *Frame) DispatchEvent(selector, typ string, eventInit any, opts *FrameDispatchEventOptions) error {
	f.log.Debugf("Frame:DispatchEvent", "fid:%s furl:%q sel:%q typ:%q", f.ID(), f.URL(), selector, typ)

	if err := f.dispatchEvent(selector, typ, eventInit, opts); err != nil {
		return fmt.Errorf("dispatching frame event %q to %q: %w", typ, selector, err)
	}
	applySlowMo(f.ctx)

	return nil
}

// dispatchEvent is like DispatchEvent but takes parsed options and neither throws
// an error, or applies slow motion.
func (f *Frame) dispatchEvent(selector, typ string, eventInit any, opts *FrameDispatchEventOptions) error {
	dispatchEvent := func(apiCtx context.Context, handle *ElementHandle) (any, error) {
		return handle.dispatchEvent(apiCtx, typ, eventInit)
	}
	const (
		force       = false
		noWaitAfter = false
	)
	act := f.newAction(
		selector, DOMElementStateAttached, opts.Strict, dispatchEvent, []string{},

View on GitHub (pinned to 93accf6570)

Solutions

  1. waitForSelector(sel, { state: 'attached' }) before dispatchEvent and raise the timeout.
  2. Keep eventInit to plain serializable data (bubbles, cancelable, detail with primitives).
  3. Verify the selector matches exactly one element in the target frame.

Example fix

// before
frame.dispatchEvent('#q', 'change', { detail: callback }); // function not serializable

// after
await frame.waitForSelector('#q', { state: 'attached' });
frame.dispatchEvent('#q', 'change', { bubbles: true, detail: { value: 'k6' } });
Defensive patterns

Strategy: validation

Validate before calling

await frame.waitForSelector(sel, { state: 'attached', timeout: 30000 });
const serializable = (v) => { try { JSON.stringify(v); return true; } catch { return false; } }; // check eventInit before passing

Try / catch

try {
  frame.dispatchEvent(sel, typ, eventInit, { timeout: 30000 });
} catch (e) {
  console.warn(`dispatchEvent(${typ}) on ${sel} failed:`, e.message);
}

Prevention

When it happens

Trigger: Dispatching to a selector that matches nothing within opts.Timeout; eventInit containing non-serializable values (functions, handles); frame navigating during dispatch; multiple strict-mode matches.

Common situations: Simulating 'input'/'change' events on fields rendered after async fetches; passing complex eventInit objects; dispatching on elements inside iframes from the main frame.

Related errors


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