{"record":{"id":"a63e0f2e76d0882b","repo":"grafana/k6","slug":"method-q-is-invalid","errorCode":null,"errorMessage":"method %q is invalid","messagePattern":"method %q is invalid","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/page.go","lineNumber":456,"sourceCode":"\n// Tag will find the first match given the URLTagPatterns and the URL from\n// the metric tag and update the name field.\nfunc (e *MetricEvent) Tag(rm RegExMatcher, matches TagMatches) error {\n\tname := strings.TrimSpace(matches.TagName)\n\tif name == \"\" {\n\t\treturn fmt.Errorf(\"name %q is invalid\", matches.TagName)\n\t}\n\n\tfor _, m := range matches.Matches {\n\t\t// Validate the request method type if it has been assigned in a Match.\n\t\tmethod := strings.TrimSpace(m.Method)\n\t\tif method != \"\" {\n\t\t\tmethod = strings.ToUpper(method)\n\t\t\tswitch method {\n\t\t\tcase http.MethodGet, http.MethodPost, http.MethodPut, http.MethodDelete, http.MethodPatch,\n\t\t\t\thttp.MethodHead, http.MethodOptions, http.MethodConnect, http.MethodTrace:\n\t\t\tdefault:\n\t\t\t\treturn fmt.Errorf(\"method %q is invalid\", m.Method)\n\t\t\t}\n\n\t\t\tif method != e.method {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\t// matchesRegex is a function that will perform the regex test in the Sobek\n\t\t// runtime.\n\t\tmatched, err := rm(m.URLRegEx, e.url)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif matched {\n\t\t\te.isUserURLTagNameExist = true\n\t\t\te.userProvidedURLTagName = name\n\t\t\treturn nil","sourceCodeStart":438,"sourceCodeEnd":474,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/page.go#L438-L474","documentation":"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.","triggerScenarios":"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'.","commonSituations":"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.","solutions":["Use one of the nine HTTP verbs, or omit method entirely to match all","For 'XHR vs document' distinctions, differentiate via the url regex patterns rather than method","Remember matching is case-insensitive after trimming, so 'get' is fine but 'FETCH' is not"],"exampleFix":"// before\nmetric.tag({ tagName: 'xhr', matches: [{ url: '.*', method: 'FETCH' }] });\n\n// after\nmetric.tag({ tagName: 'xhr', matches: [{ url: '^https?://.*' }] }); // or method: 'GET' etc.","handlingStrategy":"type-guard","validationCode":"const METHODS = new Set(['GET','POST','PUT','DELETE','PATCH','HEAD','OPTIONS','CONNECT','TRACE']);","typeGuard":"function isValidMethod(m) {\n  return m === undefined || m === '' || METHODS.has(String(m).trim().toUpperCase());\n}","tryCatchPattern":"if (!isValidMethod(m.method)) { m.method = ''; } // drop invalid method, match on URL only\nmetric.tag(matches);","preventionTips":["Use one of the nine HTTP verbs or omit method to match all requests","Differentiate XHR vs document by URL regex, not by invented methods like 'FETCH'","Reuse a shared validator for both tagName and method when building tag rules"],"tags":["browser","metrics","tagging","http-method","validation"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}