grafana/k6 · error

parsing wait for event options: %w

Error message

parsing wait for event options: %w

What it means

browserContext.waitForEvent(event, optsOrPredicate) parses its second argument with parseWaitForEventOptions, which accepts nullish (defaults), a callable predicate function, or an object of {predicate, timeout}. This outer wrapper catches whatever that parser returns: a `predicate` value that is not callable, or an unknown key in the options object. It is thrown synchronously (the mapping returns (nil, err)), not as a rejected promise.

Source

Thrown at internal/js/modules/k6/browser/browser/browser_context_mapping.go:123

			if err != nil {
				return nil, fmt.Errorf("parsing HTTP credentials: %w", err)
			}
			return promise(vu, func() (any, error) {
				return nil, bc.SetHTTPCredentials(creds) //nolint:staticcheck
			}), nil
		},
		"setOffline": func(offline bool) *sobek.Promise {
			return promise(vu, func() (any, error) {
				return nil, bc.SetOffline(offline) //nolint:wrapcheck
			})
		},
		"waitForEvent": func(event string, optsOrPredicate sobek.Value) (*sobek.Promise, error) {
			rt := vu.Runtime()
			ctx := vu.Context()

			popts, err := parseWaitForEventOptions(rt, optsOrPredicate, bc.Timeout())
			if err != nil {
				return nil, fmt.Errorf("parsing wait for event options: %w", err)
			}

			// Waits until the first event if no predicate is specified.
			var pred func(p *common.Page) (bool, error)

			// Waits until the event that satisfies the predicate.
			if popts.PredicateFn != nil {
				pred = func(p *common.Page) (bool, error) {
					return queueTask(ctx, vu.get(ctx, p.TargetID()), func() (bool, error) {
						v, err := popts.PredicateFn(rt.ToValue(p))
						if err != nil {
							return false, err
						}
						return v.ToBoolean(), nil
					})()
				}
			}

View on GitHub (pinned to 93accf6570)

Solutions

  1. Pass a function as the second argument for a plain predicate: waitForEvent('page', (p) => p.url().includes('k6.io'))
  2. Or pass an options object limited to { predicate: fn, timeout: ms }
  3. Read the wrapped cause after the colon - 'predicate function is not callable' vs 'unknown option: X' pinpoints the exact mistake

Example fix

// before: predicate given as a string
await context.waitForEvent('page', { predicate: 'loaded', timeout: 5000 });

// after: predicate is a function
await context.waitForEvent('page', {
  predicate: (page) => page.url().includes('k6.io'),
  timeout: 5000,
});
Defensive patterns

Strategy: type-guard

Validate before calling

const arg = { predicate: (p) => p.url().includes('k6.io'), timeout: 5000 };
const callable = (f) => typeof f === 'function';
if (!(arg == null || callable(arg) || (typeof arg === 'object' && !Array.isArray(arg) &&
      (arg.predicate === undefined || callable(arg.predicate))))) {
  throw new TypeError('waitForEvent arg must be a function or { predicate?, timeout? }');
}
await context.waitForEvent('page', arg);

Type guard

function isWaitForEventArg(v) {
  if (v == null || typeof v === 'function') return true;
  if (typeof v !== 'object' || Array.isArray(v) || typeof v.length === 'number' && v instanceof Array) return false;
  if (typeof v === 'string') return false;
  return v.predicate === undefined || typeof v.predicate === 'function';
}

Try / catch

try {
  await context.waitForEvent('page', opts);
} catch (e) {
  // thrown synchronously by the mapping, so wrap the call itself
  if (String(e).includes('parsing wait for event options')) {
    console.warn('bad waitForEvent options - retrying with defaults');
    await context.waitForEvent('page');
  } else throw e;
}

Prevention

When it happens

Trigger: waitForEvent('page', { predicate: 'loaded', timeout: 5000 }) - predicate is a string, not a function; waitForEvent('page', {}) with any unrecognized key; anything Sobek's ToObject turns into a key-bearing wrapper (e.g. a plain string 'load' becomes indexed keys and fails as 'unknown option: 0').

Common situations: Naming the predicate by string instead of passing a function; passing an event name or options meant for a different waitForEvent overload; leftover properties from copied Playwright code.

Related errors


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