grafana/k6 · error

method %q is invalid

Error message

method %q is invalid

What it means

MetricEvent.Tag validates each match's request method: if m.Method is non-empty it must (case-insensitively, after TrimSpace and ToUpper) be one of GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, CONNECT, TRACE. Any other non-empty value fails before the URL regex is even evaluated.

Source

Thrown at internal/js/modules/k6/browser/common/page.go:456

// Tag will find the first match given the URLTagPatterns and the URL from
// the metric tag and update the name field.
func (e *MetricEvent) Tag(rm RegExMatcher, matches TagMatches) error {
	name := strings.TrimSpace(matches.TagName)
	if name == "" {
		return fmt.Errorf("name %q is invalid", matches.TagName)
	}

	for _, m := range matches.Matches {
		// Validate the request method type if it has been assigned in a Match.
		method := strings.TrimSpace(m.Method)
		if method != "" {
			method = strings.ToUpper(method)
			switch method {
			case http.MethodGet, http.MethodPost, http.MethodPut, http.MethodDelete, http.MethodPatch,
				http.MethodHead, http.MethodOptions, http.MethodConnect, http.MethodTrace:
			default:
				return fmt.Errorf("method %q is invalid", m.Method)
			}

			if method != e.method {
				continue
			}
		}

		// matchesRegex is a function that will perform the regex test in the Sobek
		// runtime.
		matched, err := rm(m.URLRegEx, e.url)
		if err != nil {
			return err
		}

		if matched {
			e.isUserURLTagNameExist = true
			e.userProvidedURLTagName = name
			return nil

View on GitHub (pinned to 93accf6570)

Solutions

  1. Use one of the nine HTTP verbs, or omit method entirely to match all
  2. For 'XHR vs document' distinctions, differentiate via the url regex patterns rather than method
  3. Remember matching is case-insensitive after trimming, so 'get' is fine but 'FETCH' is not

Example fix

// before
metric.tag({ tagName: 'xhr', matches: [{ url: '.*', method: 'FETCH' }] });

// after
metric.tag({ tagName: 'xhr', matches: [{ url: '^https?://.*' }] }); // or method: 'GET' etc.
Defensive patterns

Strategy: type-guard

Validate before calling

const METHODS = new Set(['GET','POST','PUT','DELETE','PATCH','HEAD','OPTIONS','CONNECT','TRACE']);

Type guard

function isValidMethod(m) {
  return m === undefined || m === '' || METHODS.has(String(m).trim().toUpperCase());
}

Try / catch

if (!isValidMethod(m.method)) { m.method = ''; } // drop invalid method, match on URL only
metric.tag(matches);

Prevention

When it happens

Trigger: Passing method: 'FETCH' | 'get2' | 'GET ' with junk | a protocol verb k6 doesn't list in a page.on('metric') handler's matches: metric.tag({ tagName: 'x', matches: [{ url: '.*', method: 'FETCH' }] }). Empty string is allowed and means 'any method'.

Common situations: Tagging rules written for modern browser APIs (FETCH, XHR) instead of HTTP verbs; typos and casing are forgiven but unknown verbs are not; copied Playwright route-match patterns reused for metric tagging.

Related errors


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