grafana/k6 · error

%q is not a valid lifecycle

Error message

%q is not a valid lifecycle

What it means

PageGotoOptions.Parse validates the waitUntil option of page.goto() against the allowlist {'load', 'domcontentloaded', 'networkidle'} (map lifecycleEventToID). An exact, case-sensitive miss returns this error before any navigation starts; it is deterministic input validation.

Source

Thrown at internal/js/modules/k6/browser/common/page_options.go:81

		Timeout:   defaultTimeout,
	}
}

// Parse parses the page go back/forward options.
func (o *PageGoBackForwardOptions) Parse(ctx context.Context, opts sobek.Value) error {
	if common.IsNullish(opts) {
		return nil
	}

	obj := opts.ToObject(k6ext.Runtime(ctx))
	for _, k := range obj.Keys() {
		switch k {
		case "waitUntil":
			lifeCycle := obj.Get(k).String()
			if l, ok := lifecycleEventToID[lifeCycle]; ok {
				o.WaitUntil = l
			} else {
				return fmt.Errorf("%q is not a valid lifecycle", lifeCycle)
			}
		case "timeout":
			o.Timeout = time.Duration(obj.Get(k).ToInteger()) * time.Millisecond
		}
	}

	return nil
}

// Parse parses the page reload options.
func (o *PageReloadOptions) 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 "waitUntil":
				lifeCycle := opts.Get(k).String()

View on GitHub (pinned to 93accf6570)

Solutions

  1. Use exactly 'load', 'domcontentloaded', or 'networkidle' (all lowercase)
  2. Prefer 'domcontentloaded' for faster, more stable waits; note networkidle is discouraged for loading pages

Example fix

// before
await page.goto('https://example.com/', { waitUntil: 'networkIdle' });

// after
await page.goto('https://example.com/', { waitUntil: 'networkidle' });
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

const isValidWaitUntil = (v) => ['load','domcontentloaded','networkidle'].includes(v);

Prevention

When it happens

Trigger: page.goto(url, { waitUntil: 'networkIdle' }) — casing error; 'domContentLoaded'; or Playwright-style 'commit'/'domcontentloaded ' with whitespace. Any value not exactly load/domcontentloaded/networkidle fails.

Common situations: Porting scripts from Playwright/Puppeteer that use different lifecycle names or casings; typos; trailing whitespace from templated config.

Related errors


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