grafana/k6 · error
parsing frame navigation options to %q: %w
Error message
parsing frame navigation options to %q: %w
What it means
The options object passed to frame.goto(url, opts) failed to parse (frame_mapping.go:207). FrameGotoOptions.Parse accepts 'referer', 'timeout', and 'waitUntil'; only an invalid waitUntil fails - it must be exactly one of 'load', 'domcontentloaded', or 'networkidle' (lifecycle.go UnmarshalText rejects anything else). The error message includes the target URL to help locate the failing call.
Source
Thrown at internal/js/modules/k6/browser/browser/frame_mapping.go:207
ml := mapLocator(vu, f.GetByText(ptext, popts))
return rt.ToValue(ml).ToObject(rt), nil
},
"getByTitle": func(title sobek.Value, opts sobek.Value) (*sobek.Object, error) {
if k6common.IsNullish(title) {
return nil, errors.New("missing required argument 'title'")
}
ptitle, popts := parseGetByBaseOptions(vu.Context(), title, false, opts)
ml := mapLocator(vu, f.GetByTitle(ptitle, popts))
return rt.ToValue(ml).ToObject(rt), nil
},
"goto": func(url string, opts sobek.Value) (*sobek.Promise, error) {
gopts := common.NewFrameGotoOptions(
f.Referrer(),
f.NavigationTimeout(),
)
if err := gopts.Parse(vu.Context(), opts); err != nil {
return nil, fmt.Errorf("parsing frame navigation options to %q: %w", url, err)
}
return promise(vu, func() (any, error) {
resp, err := f.Goto(url, gopts)
if err != nil {
return nil, err //nolint:wrapcheck
}
return mapResponse(vu, resp), nil
}), nil
},
"hover": func(selector string, opts sobek.Value) (*sobek.Promise, error) {
popts := common.NewFrameHoverOptions(f.Timeout())
if err := popts.Parse(vu.Context(), opts); err != nil {
return nil, fmt.Errorf("parsing hover options: %w", err)
}
return promise(vu, func() (any, error) {
return nil, f.Hover(selector, popts) //nolint:wrapcheck
}), nilView on GitHub (pinned to 93accf6570)
Solutions
- Use one of the exact lowercase strings: 'load', 'domcontentloaded', 'networkidle'
- Centralize the constant: const WAIT_UNTIL = Object.freeze({ LOAD: 'load', DOM: 'domcontentloaded', IDLE: 'networkidle' })
- Validate before the call: if (!['load','domcontentloaded','networkidle'].includes(opts.waitUntil)) throw ...
Example fix
// before
frame.goto('https://example.com', { waitUntil: 'networkIdle' });
// after
frame.goto('https://example.com', { waitUntil: 'networkidle' }); Defensive patterns
Strategy: validation
Validate before calling
const WAIT_UNTIL = new Set(['load', 'domcontentloaded', 'networkidle']);
if (opts?.waitUntil != null && !WAIT_UNTIL.has(opts.waitUntil)) {
throw new Error(`waitUntil must be one of: ${[...WAIT_UNTIL].join(', ')}; got ${opts.waitUntil}`);
} Type guard
function isWaitUntil(v) {
return v == null || ['load', 'domcontentloaded', 'networkidle'].includes(v);
} Try / catch
try {
const resp = await frame.goto(url, opts);
} catch (e) {
if (String(e.message).includes('parsing frame navigation options')) {
throw new Error(`bad goto options for ${url}: check waitUntil spelling`);
}
throw e; // navigation timeout / network error
} Prevention
- Use exact lowercase values: 'load', 'domcontentloaded', 'networkidle'
- Define one frozen constants object for lifecycle events and import it everywhere
- Do not copy waitUntil strings from Playwright docs blindly - casing differs
When it happens
Trigger: frame.goto('https://example.com', { waitUntil: 'networkIdle' }) (camelCase), 'loaded', 'domcontentloaded ' (trailing space), or any unsupported value - UnmarshalText returns 'invalid lifecycle event: %q; must be one of: ...' which this wrapper prepends with 'parsing frame navigation options to "<url>":'.
Common situations: Porting from Playwright/Puppeteer where casing differs or extra events exist; option objects shared across page.goto and waitForLoadState with a typo; constants defined with different capitalization ('NETWORKIDLE').
Related errors
- parsing new frame check options: %w
- parsing double click options: %w
- parsing frame dispatch event options: %w
- parsing fill options: %w
- parsing focus options: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/d257d033b7880ef2.
Report an issue: GitHub.