grafana/k6 · error

parsing goto options: %w

Error message

parsing goto options: %w

What it means

FrameGotoOptions.Parse (frame_options.go:320) validates the `waitUntil` option of frame.goto()/page.goto() by calling LifecycleEvent.UnmarshalText. Only "load", "domcontentloaded" and "networkidle" are accepted (lifecycle.go:44-48); any other string makes UnmarshalText fail and the error is wrapped with this message. The invalid value never reaches Chromium — the call is rejected locally during option parsing.

Source

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

		WaitUntil: LifecycleEventLoad,
	}
}

// Parse parses the frame goto options.
func (o *FrameGotoOptions) 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 "referer":
				o.Referer = opts.Get(k).String()
			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 goto options: %w", err)
				}
			}
		}
	}
	return nil
}

func NewFrameHoverOptions(defaultTimeout time.Duration) *FrameHoverOptions {
	return &FrameHoverOptions{
		ElementHandleHoverOptions: *NewElementHandleHoverOptions(defaultTimeout),
		Strict:                    false,
	}
}

// Parse parses the frame hover options.
func (o *FrameHoverOptions) Parse(ctx context.Context, opts sobek.Value) error {
	if err := o.ElementHandleHoverOptions.Parse(ctx, opts); err != nil {
		return err

View on GitHub (pinned to 93accf6570)

Solutions

  1. Use exactly one of: "load", "domcontentloaded", "networkidle" (lowercase) in the goto options
  2. If you copied the script from Playwright/Puppeteer, map its waitUntil values to the three k6-supported ones
  3. If the wait is too strict/loose, pick networkidle for full network quiet or domcontentloaded for a faster, weaker condition

Example fix

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

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

Strategy: validation

Validate before calling

const WAIT_UNTIL = ['load', 'domcontentloaded', 'networkidle'];
function validGotoOpts(o = {}) {
  if (o.waitUntil !== undefined && !WAIT_UNTIL.includes(o.waitUntil)) {
    throw new Error(`waitUntil must be one of ${WAIT_UNTIL.join(', ')} (got ${o.waitUntil})`);
  }
  return o;
}
page.goto(url, validGotoOpts(opts));

Type guard

function isWaitUntil(v: unknown): v is 'load' | 'domcontentloaded' | 'networkidle' {
  return v === 'load' || v === 'domcontentloaded' || v === 'networkidle';
}

Prevention

When it happens

Trigger: page.goto(url, { waitUntil: ... }) or frame.goto(url, { waitUntil: ... }) with a value such as 'network idle', 'complete', 'interactive', 'domContentLoaded', or a misspelling like 'netwrokidle'. The value is case-sensitive, so 'Load' also fails.

Common situations: Copy-pasting values from Playwright docs that k6 does not support (e.g. 'commit'), assuming space-separated names like 'network idle', or mixing capitalization from other frameworks.

Related errors


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