grafana/k6 · error

parsing goto options: %w

Error message

parsing goto options: %w

What it means

parseFrameGotoOptions parses the `waitUntil` option of page.goto / frame.goto by calling Lifecycle.UnmarshalText on the provided string. When the string is not one of the recognized lifecycle events ('load', 'domcontentloaded', 'networkidle'), UnmarshalText returns an error which k6 wraps as 'parsing goto options'.

Source

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

// parseFrameGotoOptions parses the frame goto options from a Sobek value.
func parseFrameGotoOptions(
	rt *sobek.Runtime, opts sobek.Value, defaultReferrer string, defaultTimeout time.Duration,
) (*common.FrameGotoOptions, error) {
	gopts := common.NewFrameGotoOptions(defaultReferrer, defaultTimeout)
	if k6common.IsNullish(opts) {
		return gopts, nil
	}
	obj := opts.ToObject(rt)
	for _, k := range obj.Keys() {
		switch k {
		case "referer":
			gopts.Referer = obj.Get(k).String()
		case "timeout":
			gopts.Timeout = time.Duration(obj.Get(k).ToInteger()) * time.Millisecond
		case "waitUntil":
			lifeCycle := obj.Get(k).String()
			if err := gopts.WaitUntil.UnmarshalText([]byte(lifeCycle)); err != nil {
				return gopts, fmt.Errorf("parsing goto options: %w", err)
			}
		}
	}
	return gopts, nil
}

// parseFrameSetContentOptions parses the frame setContent options from a Sobek value.
func parseFrameSetContentOptions(
	rt *sobek.Runtime, opts sobek.Value, defaultTimeout time.Duration,
) (*common.FrameSetContentOptions, error) {
	scopts := common.NewFrameSetContentOptions(defaultTimeout)
	if k6common.IsNullish(opts) {
		return scopts, nil
	}
	obj := opts.ToObject(rt)
	for _, k := range obj.Keys() {
		switch k {
		case "timeout":

View on GitHub (pinned to 8d06114777)

Solutions

  1. Use one of the valid values: 'load', 'domcontentloaded', or 'networkidle' (all lowercase)
  2. Fix casing — values are compared as plain text and are case-sensitive
  3. Check the k6 browser module documentation for supported LifecycleEvent values for your k6 version
  4. Remove waitUntil and rely on the default 'load'

Example fix

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

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

Strategy: validation

Validate before calling

const LIFECYCLE_EVENTS = ['load', 'domcontentloaded', 'networkidle'];
function validGotoOptions(opts) {
  return opts == null || opts.waitUntil === undefined || LIFECYCLE_EVENTS.includes(opts.waitUntil);
}

Type guard

function isValidLifecycle(v) {
  return ['load', 'domcontentloaded', 'networkidle'].includes(v);
}

Try / catch

try {
  await page.goto(url, { waitUntil: 'networkidle' });
} catch (e) {
  if (String(e).includes('parsing goto options')) {
    throw new Error('waitUntil must be load|domcontentloaded|networkidle: ' + e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling page.goto(url, { waitUntil: 'domContentLoaded' }) with wrong casing, or any misspelled/unsupported value such as 'commit', 'domcontentloaded ' (trailing space), 'network-idle', or a non-string like waitUntil: 2 (which is coerced to a string that fails parsing).

Common situations: Porting Playwright/Puppeteer scripts: Playwright supports 'commit' and 'domcontentloaded' but k6's browser module only supports load/domcontentloaded/networkidle; capitalization mistakes ('DOMContentLoaded'); copying docs from other tools that use different lifecycle names.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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