grafana/k6 · error
unknown option: %s
Error message
unknown option: %s
What it means
Inside parseWaitForEventOptions, the options-object branch iterates keys and only `predicate` (must be callable) and `timeout` (number, coerced to milliseconds) are recognized; every other key hits the default branch at internal/js/modules/k6/browser/browser/browser_context_mapping.go:220 and returns 'unknown option: <key>'. Users see it wrapped by the outer 'parsing wait for event options' message.
Source
Thrown at internal/js/modules/k6/browser/browser/browser_context_mapping.go:220
}
var isCallable bool
w.PredicateFn, isCallable = sobek.AssertFunction(optsOrPredicate)
if isCallable {
return w, nil
}
opts := optsOrPredicate.ToObject(rt)
for _, k := range opts.Keys() {
switch k {
case "predicate":
w.PredicateFn, isCallable = sobek.AssertFunction(opts.Get(k))
if !isCallable {
return nil, errors.New("predicate function is not callable")
}
case "timeout":
w.Timeout = time.Duration(opts.Get(k).ToInteger()) * time.Millisecond
default:
return nil, fmt.Errorf("unknown option: %s", k)
}
}
return w, nil
}
View on GitHub (pinned to 93accf6570)
Solutions
- Restrict the options object to exactly { predicate?, timeout? }
- Set a default timeout via browser/context options (setDefaultTimeout) instead of adding non-standard keys
- For a predicate-only use, pass the function directly as the second argument
Example fix
// before: extra Playwright-style property
await context.waitForEvent('console', {
predicate: (msg) => msg.type() === 'error',
timeout: 1000,
signal: ctrl.signal, // unknown option: signal
});
// after: only supported keys
await context.waitForEvent('console', {
predicate: (msg) => msg.type() === 'error',
timeout: 1000,
}); Defensive patterns
Strategy: validation
Validate before calling
// strip unsupported keys before calling
const ALLOWED = new Set(['predicate', 'timeout']);
function sanitizeWaitForEventOpts(o) {
if (o == null || typeof o === 'function') return o;
return Object.fromEntries(Object.entries(o).filter(([k]) => ALLOWED.has(k)));
}
await context.waitForEvent('page', sanitizeWaitForEventOpts(opts)); Type guard
function isKnownWaitForEventKeySet(o) {
if (typeof o !== 'object' || o === null) return false;
return Object.keys(o).every((k) => k === 'predicate' || k === 'timeout');
} Prevention
- Only { predicate, timeout } are accepted - keep option objects minimal
- Set default timeouts via context.setDefaultTimeout instead of inventing per-call keys
- Check the key named in the message and delete it or rename it to a supported one
When it happens
Trigger: waitForEvent('console', { predicate: () => true, timeout: 1000, signal: abortCtrl.signal }); typos like { timeouts: 1000 } or { timeoutMs: 1000 }; passing a string as optsOrPredicate, which ToObject turns into index keys and reports 'unknown option: 0'.
Common situations: Copying Playwright's waitForEvent options (which tolerate extra fields) into k6; IDE autocompleting unrelated option names; leftover abort-signal or polling options.
Related errors
- parsing wait for event options: %w
- parsing grant permission options: %w
- parsing geo location: %w
- parsing HTTP credentials: %w
- parsing browser.newContext options: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/2612d47be53a8477.
Report an issue: GitHub.