{"record":{"id":"09b41b475f751827","repo":"grafana/k6","slug":"strict-mode-violation-multiple-elements-returned","errorCode":null,"errorMessage":"strict mode violation, multiple elements returned for selector query","messagePattern":"strict mode violation, multiple elements returned for selector query","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/element_handle.go","lineNumber":1915,"sourceCode":"\t\t\"error:notelement\":             \"node is not an element\",\n\t\t\"error:nothtmlelement\":         \"not an HTMLElement\",\n\t\t\"error:notfillableelement\":     \"element is not an <input>, <textarea> or [contenteditable] element\",\n\t\t\"error:notfillableinputtype\":   \"input of this type cannot be filled\",\n\t\t\"error:notfillablenumberinput\": \"cannot type text into input[type=number]\",\n\t\t\"error:notvaliddate\":           \"malformed value\",\n\t\t\"error:notinput\":               \"node is not an HTMLInputElement\",\n\t\t\"error:notfile\":                \"node is not an input[type=file] element\",\n\t\t\"error:hasnovalue\":             \"node is not an HTMLInputElement or HTMLTextAreaElement or HTMLSelectElement\",\n\t\t\"error:notselect\":              \"element is not a <select> element\",\n\t\t\"error:notcheckbox\":            \"not a checkbox or radio button\",\n\t\t\"error:notmultiplefileinput\":   \"non-multiple file input can only accept single file\",\n\t\t\"error:strictmodeviolation\":    \"strict mode violation, multiple elements returned for selector query\",\n\t\t\"error:notqueryablenode\":       \"node is not queryable\",\n\t\t\"error:nthnocapture\":           \"can't query n-th element in a chained selector with capture\",\n\t\t\"error:intercept\":              \"another element is intercepting with pointer action\",\n\t}\n\tif err, ok := errs[serr]; ok {\n\t\treturn errors.New(err)\n\t}\n\n\treturn errors.New(serr)\n}\n","sourceCodeStart":1897,"sourceCodeEnd":1920,"githubUrl":"https://github.com/grafana/k6/blob/01ffac6f245854c1b8adc6a69857c76a15f90022/internal/js/modules/k6/browser/common/element_handle.go#L1897-L1920","documentation":"Mapped from the injected-script error 'error:strictmodeviolation' by errorFromDOMError (element_handle.go:1896-1916). When an element query or action runs with the strict:true option, the selector must resolve to exactly one element; if it matches two or more nodes, the operation is aborted with this error instead of silently using the first match.","triggerScenarios":"page.click('#btn', {strict: true}), frame.waitForSelector(sel, {strict: true}), or elementHandle.$(sel, {strict: true}) where the selector matches 2+ nodes. Strict is opt-in in k6 browser (options default Strict:false in frame_options.go), so this only fires when explicitly enabled or when an API path enforces it.","commonSituations":"Broad selectors like text=Submit or css=button matching repeated components (table rows, cards, nav + footer links); developers coming from Playwright where strict is the default and enabling it here exposes ambiguous selectors.","solutions":["Make the selector specific: add an id, data-testid, or scope it with a chained selector to a container","Select one match explicitly with a chained nth= part or by indexing $$(selector) results","Drop strict:true to fall back to first-match behavior (k6 default)","If ambiguity is itself the bug, use $$(selector) and assert on the expected count"],"exampleFix":"// before\nawait page.click('text=Submit', { strict: true }); // matches 2 buttons\n\n// after\nawait page.click('#order-form >> text=Submit', { strict: true });","handlingStrategy":"validation","validationCode":"// Count matches before running a strict operation\nconst matches = await page.$$('text=Submit');\nif (matches.length !== 1) {\n  throw new Error(`expected 1 'Submit', found ${matches.length}`);\n}\nawait page.click('text=Submit', { strict: true });","typeGuard":null,"tryCatchPattern":"try {\n  await page.click(sel, { strict: true });\n} catch (e) {\n  if (/strict mode violation/.test(e.message)) {\n    const all = await page.$$(sel);\n    await all[0].click(); // deliberate first-match fallback\n  } else throw e;\n}","preventionTips":["Prefer unique ids/data-testids over text selectors","When enabling strict, first assert $$(sel).length === 1","Enable strict only on selectors you have verified are unique"],"tags":["browser","selector","strict-mode","query"],"backgroundTag":"strict-mode-violation","analyzedSha":"01ffac6f245854c1b8adc6a69857c76a15f90022","analyzedAt":"2026-08-18T03:05:52.393Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}