grafana/k6 · error
waiting for navigation to URL matching %q: %w
Error message
waiting for navigation to URL matching %q: %w
What it means
Produced by handleWaitForNavigationTimeoutErrorFn when Frame.WaitForNavigation times out (or the wait context is cancelled) and opts.URL is set. The original error is wrapped in k6ext.UserFriendlyError with opts.Timeout, so the final message includes the timeout duration. It means no navigation whose URL matched the pattern completed within the timeout.
Source
Thrown at internal/js/modules/k6/browser/common/frame.go:2184
// so we need to return nil explicitly.
if resp == nil {
return nil, nil //nolint:nilnil
}
return resp, nil
}
func (f *Frame) handleWaitForNavigationTimeoutErrorFn(opts *FrameWaitForNavigationOptions) func(err error) error {
return func(err error) error {
f.log.Debugf("Frame:WaitForNavigation",
"fid:%v furl:%s timeoutCtx done: %v", f.ID(), f.URL(), err)
if err != nil {
e := &k6ext.UserFriendlyError{
Err: err,
Timeout: opts.Timeout,
}
if opts.URL != "" {
return fmt.Errorf("waiting for navigation to URL matching %q: %w", opts.URL, e)
}
return fmt.Errorf("waiting for navigation: %w", e)
}
return nil
}
}
// WaitForSelector waits for the given selector to match the waiting criteria.
func (f *Frame) WaitForSelector(selector string, popts *FrameWaitForSelectorOptions) (*ElementHandle, error) {
handle, err := f.waitForSelectorRetry(selector, popts, maxRetry)
if err != nil {
return nil, fmt.Errorf("waiting for selector %q: %w", selector, err)
}
return handle, nil
}
View on GitHub (pinned to 93accf6570)
Solutions
- Use the paired form: const nav = page.waitForNavigation({url: p}); await el.click(); await nav;
- Verify the pattern actually matches the target URL (try it against the known URL first)
- Raise timeout: { url: p, timeout: 60_000 }
Example fix
// before
const [nav] = [page.waitForNavigation({ url: '**/orders**' })];
await page.click('#submit'); // navigation happens before wait registers / or URL differs
// after
const navP = page.waitForNavigation({ url: '**/orders**', timeout: 60_000 });
await page.click('#submit');
await navP; Defensive patterns
Strategy: retry
Type guard
function isNavTimeout(e) {
return e instanceof Error && /waiting for navigation to URL matching/.test(e.message);
} Try / catch
try {
const nav = page.waitForNavigation({ url: '**/orders**', timeout: 60_000 });
await el.click();
await nav;
} catch (e) {
if (isNavTimeout(e)) { /* verify current URL; maybe already there */ }
throw e;
} Prevention
- Always pair waitForNavigation with its trigger action
- Pre-test the pattern against the known target URL
- Set timeout proportional to page weight
When it happens
Trigger: page.waitForNavigation({ url: pattern, timeout: N }) where no matching navigation starts or finishes in N ms; the triggering action (click on the link) fails or points elsewhere; the URL matches but the lifecycle wait (load state of the new document) exceeds the timeout.
Common situations: Forgetting that waitForNavigation must be paired with the action that triggers it (Promise.all pattern); pattern that never matches the actual target URL; default 30s timeout too short on slow environments.
Related errors
- waiting for navigation: %w
- browser.on promise rejected: %w
- %w: %w
- finding iframe with selector %q: %w
- clicking on element: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/e72f5dd16afad8ac.
Report an issue: GitHub.