grafana/k6 · error

parsing waitForEvent options

Error message

parsing waitForEvent options: %w

What it means

Thrown by page.waitForEvent(eventName, opts) when parsePageWaitForEventOptions rejects the options object. The accepted keys are exactly 'timeout' (integer milliseconds) and 'predicate' (a function); unknown keys produce "waitForEvent does not support option: '%s'" and a non-callable predicate produces "predicate must be a function", both wrapped in this message.

Solutions

  1. Restrict the options object to { timeout: <ms>, predicate: (event) => boolean }.
  2. Move URL filtering into the predicate: { predicate: e => e.url().includes('/api') }.
  3. Express timeouts as plain millisecond numbers, never strings.
  4. Omit the second argument to use the page default timeout when no custom behavior is needed.

Example fix

// before
await page.waitForEvent('response', { url: '**/api/users' });

// after
await page.waitForEvent('response', { predicate: r => r.url().includes('/api/users') });
Defensive patterns

Strategy: validation

Validate before calling

const opts = { timeout: 5000, predicate: e => true };
const badKeys = Object.keys(opts).filter(k => k !== 'timeout' && k !== 'predicate');
if (badKeys.length || (opts.predicate !== undefined && typeof opts.predicate !== 'function')) {
  throw new Error(`invalid waitForEvent options: ${badKeys.join(',') || 'predicate'}`);
}
await page.waitForEvent('response', opts);

Type guard

const isWaitForEventOpts = (o) => o == null || (typeof o === 'object' && Object.keys(o).every(k => k === 'timeout' || k === 'predicate') && (o.predicate === undefined || typeof o.predicate === 'function'));

Try / catch

try { await page.waitForEvent(ev, opts); } catch (e) { if (e.message.includes('parsing waitForEvent options')) { /* strip bad keys and retry */ } throw e; }

Prevention

When it happens

Trigger: Calling page.waitForEvent('response', { timeout: 5000, url: '**/api' }) (unknown key 'url'); passing predicate as a string of source code or an object; passing a timeout value whose ToInteger conversion is unintended (e.g. '30s' becomes NaN/0 ms).

Common situations: Copy-pasting Playwright options that filter by URL or predicate syntax differences; passing an inline arrow wrapped in quotes; assuming string durations like '30s' are parsed (they are not — raw milliseconds are required).

Related errors


AI-assisted analysis of grafana/k6@8d06114777 (2026-08-18). Data as JSON: /api/errors/d49576fae232e5c3. Report an issue: GitHub.

Appendix: source

Thrown at internal/js/modules/k6/browser/browser/page_mapping.go:698

				case common.PageEventConsole:
					return mapConsoleMessage(vu, pe), nil
				case common.PageEventRequest:
					return mapRequestEvent(vu, pe), nil
				case common.PageEventResponse:
					return mapResponseEvent(vu, pe), nil
				case common.PageEventRequestFinished:
					return mapRequestEvent(vu, pe), nil
				case common.PageEventRequestFailed:
					return mapRequestEvent(vu, pe), nil
				case common.PageEventMetric:
					// intentionally left blank
				}
				return nil, fmt.Errorf("waitForEvent does not support mapping for event: %q", event)
			}

			popts, fn, err := parsePageWaitForEventOptions(vu.Context(), opts, p.Timeout())
			if err != nil {
				return nil, fmt.Errorf("parsing waitForEvent options: %w", err)
			}

			ctx := vu.Context()
			tq := vu.get(ctx, p.TargetID())

			return promise(vu, func() (any, error) {
				rpe, err := p.WaitForEvent(event, popts, func(pe common.PageEvent) (bool, error) {
					if fn == nil {
						return true, nil
					}
					return queueTask(ctx, tq, func() (bool, error) {
						m, err := mapPageEvent(vu, pe)
						if err != nil {
							return false, err
						}
						v, err := fn(sobek.Undefined(), vu.Runtime().ToValue(m))
						if err != nil {
							return false, fmt.Errorf("executing waitForEvent predicate: %w", err)

View on GitHub (pinned to 8d06114777)