grafana/k6 · error
parsing frame wait for navigation options
Error message
parsing frame wait for navigation options: %w
What it means
Thrown by page.waitForNavigation(opts) (and the frame variant) when FrameWaitForNavigationOptions.Parse rejects the options object. The parser validates keys like 'timeout', 'waitUntil' and 'url'; unknown keys or invalid values (bad waitUntil string, non-numeric timeout) are wrapped in this message.
Solutions
- Use { timeout: <ms>, waitUntil: 'load' | 'domcontentloaded' | 'networkidle', url: <string|RegExp> } only.
- Replace Puppeteer waitUntil values: 'networkidle0'/'networkidle2' → 'networkidle'.
- Trigger the navigation and the wait together (click then waitForNavigation in a Promise.all) so options stay minimal.
- Prefer page.waitForURL(url, opts) for URL-targeted waits.
Example fix
// before
await Promise.all([ page.waitForNavigation({ waitUntil: 'networkidle2' }), page.click('a.next') ]);
// after
await Promise.all([ page.waitForNavigation({ waitUntil: 'networkidle' }), page.click('a.next') ]); Defensive patterns
Strategy: validation
Validate before calling
const opts = { timeout: 10000, waitUntil: 'load' };
if (!['load','domcontentloaded','networkidle'].includes(opts.waitUntil)) throw new Error(`invalid waitUntil '${opts.waitUntil}'`);
if (opts.url !== undefined && typeof opts.url !== 'string' && !(opts.url instanceof RegExp)) throw new Error('url must be string or RegExp');
await Promise.all([ page.waitForNavigation(opts), page.click('a') ]); Type guard
const isNavOpts = (o) => o == null || (typeof o === 'object' && Object.keys(o).every(k => ['timeout','waitUntil','url'].includes(k)) && [undefined,'load','domcontentloaded','networkidle'].includes(o.waitUntil));
Try / catch
try { await page.waitForNavigation(opts); } catch (e) { if (e.message.includes('parsing frame wait for navigation options')) { /* normalize waitUntil and retry */ } throw e; } Prevention
- Map Puppeteer waitUntil values ('networkidle0'/'networkidle2' → 'networkidle') during migrations.
- Keep navigation options minimal: usually just waitUntil.
- Always race waitForNavigation with the trigger action (Promise.all) so options stay small.
When it happens
Trigger: page.waitForNavigation({ waitUntil: 'networkidle2' }) (Puppeteer value); passing unknown keys; { url: 123 } where a string/regex is expected; string durations like { timeout: '10s' }.
Common situations: Migrating Puppeteer scripts (networkidle0/networkidle2 values); assuming Playwright's extra navigation options exist; racing navigation patterns where users add ad-hoc keys.
Related errors
- parsing waitForEvent options
- parsing waitForFunction options
- parsing waitForRequest options
- parsing waitForResponse options
- parsing waitForURL options
AI-assisted analysis of grafana/k6@01ffac6f24 (2026-08-18).
Data as JSON: /api/errors/6a0073a9e9e1fd21.
Report an issue: GitHub.
Appendix: source
Thrown at internal/js/modules/k6/browser/browser/page_mapping.go:992
}
purl := parseStringOrRegex(url, false)
tq, ctx, stop := newTaskQueue(vu)
return promise(vu, func() (result any, reason error) {
defer stop()
return nil, target.WaitForURL(purl, popts, newRegExMatcher(ctx, vu, tq))
}), nil
}
func mapWaitForNavigation(vu moduleVU, target interface {
Timeout() time.Duration
WaitForNavigation(*common.FrameWaitForNavigationOptions, common.RegExMatcher) (*common.Response, error)
}, opts sobek.Value,
) (*sobek.Promise, error) {
popts := common.NewFrameWaitForNavigationOptions(target.Timeout())
if err := popts.Parse(vu.Context(), opts); err != nil {
return nil, fmt.Errorf("parsing frame wait for navigation options: %w", err)
}
// Only use task queue and RegExMatcher if a URL is specified.
rm, stop := func() (common.RegExMatcher, func()) {
if popts.URL == "" {
return nil, func() {}
}
tq, ctx, stop := newTaskQueue(vu)
return newRegExMatcher(ctx, vu, tq), stop
}()
return promise(vu, func() (any, error) {
defer stop()
resp, err := target.WaitForNavigation(popts, rm)
if err != nil {
return nil, err //nolint:wrapcheck
}View on GitHub (pinned to 01ffac6f24)