grafana/k6 · error

parsing URL pattern: %w

Error message

parsing URL pattern: %w

What it means

Thrown by Frame.WaitForNavigation when newPatternMatcher cannot build a URL matcher from opts.URL. The pattern is compiled (glob-to-regex or regex via the injected RegExMatcher) before any navigation is awaited, so a syntactically invalid pattern fails immediately with this wrap. No waiting occurs; the error is pure input validation.

Source

Thrown at internal/js/modules/k6/browser/common/frame.go:2085

}

// WaitForNavigation waits for the given navigation lifecycle event to happen.
// RegExMatcher should be non-nil to be able to test against a URL pattern in the options.
//
//nolint:funlen
func (f *Frame) WaitForNavigation(opts *FrameWaitForNavigationOptions, rm RegExMatcher) (*Response, error) {
	f.log.Debugf("Frame:WaitForNavigation",
		"fid:%s furl:%s url:%s", f.ID(), f.URL(), opts.URL)
	defer f.log.Debugf("Frame:WaitForNavigation:return",
		"fid:%s furl:%s", f.ID(), f.URL())

	timeoutCtx, timeoutCancel := context.WithTimeout(f.ctx, opts.Timeout)

	// Create URL matcher based on the pattern
	matcher, err := newPatternMatcher(opts.URL, rm)
	if err != nil {
		timeoutCancel()
		return nil, fmt.Errorf("parsing URL pattern: %w", err)
	}

	var matcherErr error
	navEvtCh, navEvtCancel := createWaitForEventPredicateHandler(timeoutCtx, f, []string{EventFrameNavigation},
		func(data any) bool {
			if navEvt, ok := data.(*NavigationEvent); ok {
				// Check if the navigation URL matches the pattern
				matched, err := matcher(navEvt.url)
				if err != nil {
					matcherErr = err
					// Return true here even though it's not correct and no match
					// was found. We need this to exit asap so that the error can be
					// propagated to the caller.
					return true
				}
				return matched
			}
			return false

View on GitHub (pinned to 93accf6570)

Solutions

  1. Test the pattern in a regex tester first; remember '*' glob segments are translated but raw regex metacharacters are not escaped
  2. Use a simple glob like '**/path/**' for substring-style matches instead of hand-written regex
  3. Escape literal dots/question marks: '/search\?q=1'

Example fix

// before
page.waitForNavigation({ url: 'https://example.com/search?q=1' }); // '?' is regex

// after
page.waitForNavigation({ url: /https:\/\/example\.com\/search\?q=1/ });
// or glob form
page.waitForNavigation({ url: '**/search**' });
Defensive patterns

Strategy: validation

Validate before calling

function assertPattern(p) {
  new RegExp(p.replace(/\*\*/g, '.*').replace(/\*/g, '[^/]*'));
}
assertPattern(cfg.urlPattern); // throws early on malformed patterns

Type guard

function isPatternError(e) {
  return e instanceof Error && /parsing URL pattern/.test(e.message);
}

Prevention

When it happens

Trigger: page.waitForNavigation({ url: '(unclosed' }) or any malformed regex; a glob containing characters that break the generated regex; passing a full URL where a pattern with regex metacharacters (dots, question marks) is interpreted as regex.

Common situations: Treating the url option as a plain string match (it is a pattern); unescaped query strings like '/search?q=1' where '?' is regex syntax; porting selectors between glob and regex dialects.

Related errors


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