{"record":{"id":"5b3a9865f4b5303f","repo":"grafana/k6","slug":"missing-required-argument-role-5b3a98","errorCode":null,"errorMessage":"missing required argument 'role'","messagePattern":"missing required argument 'role'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/browser/page_mapping.go","lineNumber":173,"sourceCode":"\t\t\"getAttribute\": func(selector string, name string, opts sobek.Value) (*sobek.Promise, error) {\n\t\t\tpopts := common.NewFrameBaseOptions(p.MainFrame().Timeout())\n\t\t\tif err := parseFrameBaseOptions(popts, rt, opts); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"parsing getAttribute options: %w\", err)\n\t\t\t}\n\t\t\treturn promise(vu, func() (any, error) {\n\t\t\t\ts, ok, err := p.GetAttribute(selector, name, popts)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err //nolint:wrapcheck\n\t\t\t\t}\n\t\t\t\tif !ok {\n\t\t\t\t\treturn nil, nil //nolint:nilnil\n\t\t\t\t}\n\t\t\t\treturn s, nil\n\t\t\t}), nil\n\t\t},\n\t\t\"getByRole\": func(role sobek.Value, opts sobek.Value) (*sobek.Object, error) {\n\t\t\tif k6common.IsNullish(role) {\n\t\t\t\treturn nil, errors.New(\"missing required argument 'role'\")\n\t\t\t}\n\t\t\tpopts := parseGetByRoleOptions(vu.Context(), opts)\n\n\t\t\tml := mapLocator(vu, p.GetByRole(role.String(), popts))\n\t\t\treturn rt.ToValue(ml).ToObject(rt), nil\n\t\t},\n\t\t\"getByAltText\": func(alt sobek.Value, opts sobek.Value) (*sobek.Object, error) {\n\t\t\tif k6common.IsNullish(alt) {\n\t\t\t\treturn nil, errors.New(\"missing required argument 'altText'\")\n\t\t\t}\n\t\t\tpalt, popts := parseGetByBaseOptions(vu.Context(), alt, false, opts)\n\n\t\t\tml := mapLocator(vu, p.GetByAltText(palt, popts))\n\t\t\treturn rt.ToValue(ml).ToObject(rt), nil\n\t\t},\n\t\t\"getByLabel\": func(label sobek.Value, opts sobek.Value) (*sobek.Object, error) {\n\t\t\tif k6common.IsNullish(label) {\n\t\t\t\treturn nil, errors.New(\"missing required argument 'label'\")","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/grafana/k6/blob/8d06114777191d21ef885d05c5f8aa9e1ed838ae/internal/js/modules/k6/browser/browser/page_mapping.go#L155-L191","documentation":"Thrown by page.getByRole() in the k6 browser module (internal/js/modules/k6/browser/browser/page_mapping.go:173). The role argument is mandatory and is converted with role.String() into an ARIA role selector; the nullish guard fails immediately for nil/undefined/null because no CDP query can be built. A role that is present but not a real ARIA role passes this check and instead yields a locator matching nothing.","triggerScenarios":"Calling page.getByRole() with zero arguments; passing undefined/null explicitly; passing a role variable that a helper function failed to populate (e.g. mapEntry lookup miss).","commonSituations":"Role-driven selectors parameterized from scenario env or data files with missing values; refactoring a selector helper so the role parameter stopped being forwarded; ported Playwright snippets with the first argument omitted.","solutions":["Pass a valid ARIA role string: page.getByRole('button'), page.getByRole('link', { name: 'Sign in' })","Default dynamic roles: const role = cfg.role ?? 'button'","Verify the role against the standard ARIA role list before passing it","Log the role value just before the call to locate the undefined producer"],"exampleFix":"// before\nconst btn = page.getByRole(SEL.submit.role); // SEL.submit undefined\n\n// after\nconst btn = page.getByRole(SEL?.submit?.role ?? 'button', { name: 'Submit' });","handlingStrategy":"validation","validationCode":"const role = SEL?.submit?.role ?? 'button';\nif (role === undefined || role === null) throw new Error('role is required');\nconst loc = page.getByRole(role);","typeGuard":"const ARIA_ROLES = new Set(['button', 'link', 'textbox', 'checkbox', 'radio', 'heading', 'listitem', 'list', 'navigation', 'menuitem', 'option', 'img']);\nfunction isRole(v) { return typeof v === 'string' && ARIA_ROLES.has(v); }\n// usage: if (!isRole(role)) throw new Error(`invalid or missing ARIA role: ${role}`);","tryCatchPattern":"try {\n  const loc = page.getByRole(role);\n} catch (e) {\n  if (/missing required argument 'role'/.test(e.message)) throw new Error('getByRole called without a role — check your selector config');\n  throw e;\n}","preventionTips":["Always pass an explicit role literal or a defaulted variable","Use optional chaining plus ?? when reading roles from nested selector configs","Cross-check role names against the ARIA role list once when writing the helper","Let k6 browser typings flag zero-argument calls in the editor"],"tags":["browser","page","aria-role","argument-validation","api-misuse"],"backgroundTag":"missing-required-argument","analyzedSha":"8d06114777191d21ef885d05c5f8aa9e1ed838ae","analyzedAt":"2026-08-18T03:05:52.393Z","contentChangedAt":"2026-08-18T03:05:52.393Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}