grafana/k6 · error

parsing waitForURL options: %w

Error message

parsing waitForURL options: %w

What it means

FrameWaitForURLOptions.Parse (frame_options.go:826) validates the `waitUntil` option of frame.waitForURL()/page.waitForURL() with LifecycleEvent.UnmarshalText. Only "load", "domcontentloaded" and "networkidle" are legal; any other value fails parsing with this wrapped error and the wait is never started.

Source

Thrown at internal/js/modules/k6/browser/common/frame_options.go:826

	return &FrameWaitForURLOptions{
		Timeout:   defaultTimeout,
		WaitUntil: LifecycleEventLoad,
	}
}

// Parse parses the frame waitForURL options.
func (o *FrameWaitForURLOptions) Parse(ctx context.Context, opts sobek.Value) error {
	rt := k6ext.Runtime(ctx)
	if !common.IsNullish(opts) {
		opts := opts.ToObject(rt)
		for _, k := range opts.Keys() {
			switch k {
			case "timeout":
				o.Timeout = time.Duration(opts.Get(k).ToInteger()) * time.Millisecond
			case "waitUntil":
				lifeCycle := opts.Get(k).String()
				if err := o.WaitUntil.UnmarshalText([]byte(lifeCycle)); err != nil {
					return fmt.Errorf("parsing waitForURL options: %w", err)
				}
			}
		}
	}
	return nil
}

View on GitHub (pinned to 93accf6570)

Solutions

  1. Pass "load", "domcontentloaded" or "networkidle" exactly as waitUntil
  2. Put the URL pattern in the first argument, not inside the options object
  3. Reuse a single validated options constant across all navigation-wait calls in the script

Example fix

// before
page.waitForURL('**/dashboard', { waitUntil: 'loaded' });

// after
page.waitForURL('**/dashboard', { waitUntil: 'load' });
Defensive patterns

Strategy: validation

Validate before calling

const WAIT_UNTIL = ['load', 'domcontentloaded', 'networkidle'];
if (opts && opts.waitUntil !== undefined && !WAIT_UNTIL.includes(opts.waitUntil)) {
  throw new Error(`invalid waitUntil: ${opts.waitUntil}`);
}
page.waitForURL(pattern, opts);

Type guard

function isWaitUntil(v: unknown): v is 'load' | 'domcontentloaded' | 'networkidle' {
  return typeof v === 'string' && ['load', 'domcontentloaded', 'networkidle'].includes(v);
}

Prevention

When it happens

Trigger: page.waitForURL('https://example.com/done', { waitUntil: 'idle' }) or { waitUntil: 'Load' }. The parser only reads the `timeout` (ms) and `waitUntil` keys; the URL itself is a positional argument, not an option key.

Common situations: Copying waitUntil spellings from other tooling or docs, or sharing an options object between waitForURL and custom code that uses different lifecycle vocabulary.

Related errors


AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15). Data as JSON: /api/errors/6ce2861842984f5e. Report an issue: GitHub.