grafana/k6 · error

parsing waitForLoadState

Error message

parsing waitForLoadState %q options: %w

What it means

Thrown while parsing the options object of frame.waitForLoadState(state, options) (browser/frame_mapping.go:448); the requested state is echoed via %q. FrameWaitForLoadStateOptions.Parse reads only timeout (coercively) and cannot fail in current k6, so the wrap is defensive. An invalid state string such as 'networkIdle' fails separately inside WaitForLoadState with a lifecycle-event error, not here.

Solutions

  1. Keep options to a plain { timeout: <number> } object
  2. Pass the state as the first argument, lowercase: 'load' | 'domcontentloaded' | 'networkidle'
  3. Omit options to use the frame default timeout
  4. Upgrade k6 if you hit this with an ordinary options object

Example fix

// before
frame.waitForLoadState('networkIdle', { timeout: '5000' });
// after
frame.waitForLoadState('networkidle', { timeout: 5000 });
Defensive patterns

Strategy: validation

Validate before calling

const STATES = ['load', 'domcontentloaded', 'networkidle'];
if (!STATES.includes(state)) throw new Error(`state must be one of ${STATES.join('|')}`);
const o = { ...(opts?.timeout !== undefined && { timeout: Number(opts.timeout) }) };

Type guard

function isWaitForLoadStateArgs(state, o) {
  return ['load', 'domcontentloaded', 'networkidle'].includes(state) &&
    (o == null || typeof o === 'object' && (o.timeout === undefined || typeof o.timeout === 'number'));
}

Try / catch

try { await frame.waitForLoadState(state, o); } catch (e) { if (!String(e.message).includes('waitForLoadState')) throw e; }

Prevention

When it happens

Trigger: Exotic options values (Symbol, throwing getters) that sobek cannot traverse; older k6 builds with stricter option export; passing the state in the options object instead of as the first argument is silently ignored, which often precedes a state error elsewhere.

Common situations: Casing mistakes copied from other tools ('networkIdle' vs the supported 'load', 'domcontentloaded', 'networkidle'); options built from parsed JSON; k6 version drift in parser strictness.

Related errors


AI-assisted analysis of grafana/k6@8d06114777 (2026-09-14). Data as JSON: /api/errors/c14a165fc36bea8e. Report an issue: GitHub.

Appendix: source

Thrown at internal/js/modules/k6/browser/browser/frame_mapping.go:446

			}), nil
		},
		"url": f.URL,
		"waitForFunction": func(pageFunc, opts sobek.Value, args ...sobek.Value) (*sobek.Promise, error) {
			js, popts, pargs, err := parseWaitForFunctionArgs(
				rt, f.Timeout(), pageFunc, opts, args...,
			)
			if err != nil {
				return nil, fmt.Errorf("frame waitForFunction: %w", err)
			}

			return promise(vu, func() (result any, reason error) {
				return f.WaitForFunction(js, popts, pargs...) //nolint:wrapcheck
			}), nil
		},
		"waitForLoadState": func(state string, opts sobek.Value) (*sobek.Promise, error) {
			popts, err := parseFrameWaitForLoadStateOptions(rt, opts, f.Timeout())
			if err != nil {
				return nil, fmt.Errorf("parsing waitForLoadState %q options: %w", state, err)
			}

			return promise(vu, func() (any, error) {
				return nil, f.WaitForLoadState(state, popts) //nolint:wrapcheck
			}), nil
		},
		"waitForNavigation": func(opts sobek.Value) (*sobek.Promise, error) {
			return mapWaitForNavigation(rt, vu, f, opts)
		},
		"waitForSelector": func(selector string, opts sobek.Value) (*sobek.Promise, error) {
			popts, err := parseFrameWaitForSelectorOptions(rt, opts, f.Timeout())
			if err != nil {
				return nil, fmt.Errorf("parsing wait for selector %q options: %w", selector, err)
			}

			return promise(vu, func() (any, error) {
				eh, err := f.WaitForSelector(selector, popts)
				if err != nil {

View on GitHub (pinned to 8d06114777)