{"record":{"id":"0ac5f2ff3984fdbf","repo":"grafana/k6","slug":"parsing-waitforfunction-options-w","errorCode":null,"errorMessage":"parsing waitForFunction options: %w","messagePattern":"parsing waitForFunction options: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/browser/page_mapping.go","lineNumber":822,"sourceCode":"\t\t\t\treturn nil, nil\n\t\t\t})\n\t\t\tif pageEvent.wait {\n\t\t\t\tif _, err := wait(); errors.Is(err, context.Canceled) {\n\t\t\t\t\treturn errors.New(\"iteration ended before page.on handler completed executing\")\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\t}\n}\n\nfunc parseWaitForFunctionArgs(\n\tctx context.Context, timeout time.Duration, pageFunc, opts sobek.Value, gargs ...sobek.Value,\n) (string, *common.FrameWaitForFunctionOptions, []any, error) {\n\tpopts := common.NewFrameWaitForFunctionOptions(timeout)\n\terr := popts.Parse(ctx, opts)\n\tif err != nil {\n\t\treturn \"\", nil, nil, fmt.Errorf(\"parsing waitForFunction options: %w\", err)\n\t}\n\n\tjs := pageFunc.ToString().String()\n\t_, isCallable := sobek.AssertFunction(pageFunc)\n\tif !isCallable {\n\t\tjs = fmt.Sprintf(\"() => (%s)\", js)\n\t}\n\n\treturn js, popts, exportArgs(gargs), nil\n}\n\n// parseStringOrRegex parses a sobek.Value to return either a quoted string if it was a string,\n// or a raw string if it was a JS RegExp object or another type.\n//\n// Some getBy* APIs work with single quotes and some work with double quotes.\n// This inconsistency seems to stem from the injected code copied from\n// Playwright itself.\n//","sourceCodeStart":804,"sourceCodeEnd":840,"githubUrl":"https://github.com/grafana/k6/blob/01ffac6f245854c1b8adc6a69857c76a15f90022/internal/js/modules/k6/browser/browser/page_mapping.go#L804-L840","documentation":"Thrown when parsing the third argument of page.waitForFunction(fn, arg, opts) (or the frame equivalent) fails. NewFrameWaitForFunctionOptions.Parse validates the options object; unsupported keys or invalid values — notably a bad 'polling' value (must be the string 'raf' or a millisecond number) — surface wrapped in this error.","triggerScenarios":"page.waitForFunction(fn, {}, { polling: 'interval' }) (only 'raf' or a number are valid); passing unknown keys; passing a string timeout; passing options in the second argument position (arg and opts swapped).","commonSituations":"Porting Puppeteer/Playwright snippets where polling semantics or key names differ; swapping the arg and opts parameters (k6 signature is waitForFunction(pageFunction, arg, options)); using Playwright-style polling: 'raf' together with extra keys k6 rejects.","solutions":["Pass options as the third argument: page.waitForFunction(fn, arg, { polling: 'raf', timeout: 30000 }).","Use polling: 'raf' or a plain number of milliseconds; never other strings.","Remove any key other than 'polling' and 'timeout' from the options object.","Omit options entirely for the default (requestAnimationFrame-less polling with default timeout)."],"exampleFix":"// before\nawait page.waitForFunction(() => window.ready, { polling: 250, timeout: 5000 });\n\n// after\nawait page.waitForFunction(() => window.ready, null, { polling: 250, timeout: 5000 });","handlingStrategy":"validation","validationCode":"const opts = { polling: 'raf', timeout: 30000 };\nif (opts.polling !== 'raf' && !Number.isFinite(opts.polling)) throw new Error('polling must be \\'raf\\' or a millisecond number');\nif (Object.keys(opts).some(k => k !== 'polling' && k !== 'timeout')) throw new Error('unsupported waitForFunction option');\nawait page.waitForFunction(() => window.ready, null, opts);","typeGuard":"const isWaitForFunctionOpts = (o) => o == null || (typeof o === 'object' && Object.keys(o).every(k => k === 'polling' || k === 'timeout') && (o.polling === undefined || o.polling === 'raf' || Number.isFinite(o.polling)));","tryCatchPattern":"try { await page.waitForFunction(fn, arg, opts); } catch (e) { if (e.message.includes('parsing waitForFunction options')) { /* correct arg/opts positions */ } throw e; }","preventionTips":["Remember the signature waitForFunction(pageFunction, arg, options) — options go third.","Use polling 'raf' or a millisecond number; never 'interval' or strings.","Smoke-test waitForFunction calls once at script start to catch option errors before load begins."],"tags":["k6","browser","page","waitforfunction","options","argument-validation"],"backgroundTag":"invalid-options-object","analyzedSha":"01ffac6f245854c1b8adc6a69857c76a15f90022","analyzedAt":"2026-08-18T03:05:52.393Z","contentChangedAt":"2026-08-18T03:05:52.393Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}