grafana/k6 · error

parsing waitForFunction options

Error message

parsing waitForFunction options: %w

What it means

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.

Solutions

  1. Pass options as the third argument: page.waitForFunction(fn, arg, { polling: 'raf', timeout: 30000 }).
  2. Use polling: 'raf' or a plain number of milliseconds; never other strings.
  3. Remove any key other than 'polling' and 'timeout' from the options object.
  4. Omit options entirely for the default (requestAnimationFrame-less polling with default timeout).

Example fix

// before
await page.waitForFunction(() => window.ready, { polling: 250, timeout: 5000 });

// after
await page.waitForFunction(() => window.ready, null, { polling: 250, timeout: 5000 });
Defensive patterns

Strategy: validation

Validate before calling

const opts = { polling: 'raf', timeout: 30000 };
if (opts.polling !== 'raf' && !Number.isFinite(opts.polling)) throw new Error('polling must be \'raf\' or a millisecond number');
if (Object.keys(opts).some(k => k !== 'polling' && k !== 'timeout')) throw new Error('unsupported waitForFunction option');
await page.waitForFunction(() => window.ready, null, opts);

Type guard

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)));

Try / catch

try { await page.waitForFunction(fn, arg, opts); } catch (e) { if (e.message.includes('parsing waitForFunction options')) { /* correct arg/opts positions */ } throw e; }

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of grafana/k6@01ffac6f24 (2026-08-18). Data as JSON: /api/errors/0ac5f2ff3984fdbf. Report an issue: GitHub.

Appendix: source

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

				return nil, nil
			})
			if pageEvent.wait {
				if _, err := wait(); errors.Is(err, context.Canceled) {
					return errors.New("iteration ended before page.on handler completed executing")
				}
			}
			return nil
		})
	}
}

func parseWaitForFunctionArgs(
	ctx context.Context, timeout time.Duration, pageFunc, opts sobek.Value, gargs ...sobek.Value,
) (string, *common.FrameWaitForFunctionOptions, []any, error) {
	popts := common.NewFrameWaitForFunctionOptions(timeout)
	err := popts.Parse(ctx, opts)
	if err != nil {
		return "", nil, nil, fmt.Errorf("parsing waitForFunction options: %w", err)
	}

	js := pageFunc.ToString().String()
	_, isCallable := sobek.AssertFunction(pageFunc)
	if !isCallable {
		js = fmt.Sprintf("() => (%s)", js)
	}

	return js, popts, exportArgs(gargs), nil
}

// parseStringOrRegex parses a sobek.Value to return either a quoted string if it was a string,
// or a raw string if it was a JS RegExp object or another type.
//
// Some getBy* APIs work with single quotes and some work with double quotes.
// This inconsistency seems to stem from the injected code copied from
// Playwright itself.
//

View on GitHub (pinned to 01ffac6f24)