{"record":{"id":"2612d47be53a8477","repo":"grafana/k6","slug":"unknown-option-s","errorCode":null,"errorMessage":"unknown option: %s","messagePattern":"unknown option: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/browser/browser_context_mapping.go","lineNumber":220,"sourceCode":"\t}\n\tvar isCallable bool\n\tw.PredicateFn, isCallable = sobek.AssertFunction(optsOrPredicate)\n\tif isCallable {\n\t\treturn w, nil\n\t}\n\n\topts := optsOrPredicate.ToObject(rt)\n\tfor _, k := range opts.Keys() {\n\t\tswitch k {\n\t\tcase \"predicate\":\n\t\t\tw.PredicateFn, isCallable = sobek.AssertFunction(opts.Get(k))\n\t\t\tif !isCallable {\n\t\t\t\treturn nil, errors.New(\"predicate function is not callable\")\n\t\t\t}\n\t\tcase \"timeout\":\n\t\t\tw.Timeout = time.Duration(opts.Get(k).ToInteger()) * time.Millisecond\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"unknown option: %s\", k)\n\t\t}\n\t}\n\n\treturn w, nil\n}\n","sourceCodeStart":202,"sourceCodeEnd":226,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/browser/browser_context_mapping.go#L202-L226","documentation":"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.","triggerScenarios":"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'.","commonSituations":"Copying Playwright's waitForEvent options (which tolerate extra fields) into k6; IDE autocompleting unrelated option names; leftover abort-signal or polling options.","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"],"exampleFix":"// before: extra Playwright-style property\nawait context.waitForEvent('console', {\n  predicate: (msg) => msg.type() === 'error',\n  timeout: 1000,\n  signal: ctrl.signal, // unknown option: signal\n});\n\n// after: only supported keys\nawait context.waitForEvent('console', {\n  predicate: (msg) => msg.type() === 'error',\n  timeout: 1000,\n});","handlingStrategy":"validation","validationCode":"// strip unsupported keys before calling\nconst ALLOWED = new Set(['predicate', 'timeout']);\nfunction sanitizeWaitForEventOpts(o) {\n  if (o == null || typeof o === 'function') return o;\n  return Object.fromEntries(Object.entries(o).filter(([k]) => ALLOWED.has(k)));\n}\nawait context.waitForEvent('page', sanitizeWaitForEventOpts(opts));","typeGuard":"function isKnownWaitForEventKeySet(o) {\n  if (typeof o !== 'object' || o === null) return false;\n  return Object.keys(o).every((k) => k === 'predicate' || k === 'timeout');\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["browser","wait-for-event","unknown-option","options-parsing"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}