{"record":{"id":"924689166d95ae6b","repo":"grafana/k6","slug":"can-t-query-n-th-element-in-a-chained-selector-wit","errorCode":null,"errorMessage":"can't query n-th element in a chained selector with capture","messagePattern":"can't query n-th element in a chained selector with capture","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 'error:nthnocapture' by errorFromDOMError (element_handle.go:1896-1916). k6 browser chained selectors (parts joined with '>>') may prefix one part with '*' to capture the element resolved by an intermediate part (selectors.go:44-46). The injected script refuses positional nth= queries inside a chain that uses such a capture, because the n-th index cannot be applied to the captured result.","triggerScenarios":"A selector string combining a '*' capture prefix with an nth= part in the same chain, e.g. page.$('*css=div.item >> nth=1') or similar chains passed to frame.click/page.waitForSelector. Selector parts are split on '>>' by Selector.parse (selectors.go:82+) and the engine rejects this combination.","commonSituations":"Building selectors programmatically by concatenating fragments; porting Playwright locator chains (locator.nth()) into k6 chained selector strings.","solutions":["Remove either the '*' capture prefix or the nth= part so the chain has only one of them","Split the work: run the chained query to get the captured element, then use $$/nth on the result in a second query","Rewrite as two explicit queries: first resolve the container, then index into its matches"],"exampleFix":"// before\nconst el = await page.$('*css=div.item >> nth=1'); // nth with capture\n\n// after\nconst items = await page.$$('css=div.item');\nconst el = items[1];","handlingStrategy":"validation","validationCode":"// Reject capture+nth chains before using them\nfunction isSafeSelector(sel) {\n  const parts = sel.split('>>');\n  const hasCapture = parts.some(p => p.trim().startsWith('*'));\n  const hasNth = parts.some(p => /nth\\s*=/.test(p));\n  return !(hasCapture && hasNth);\n}\nif (!isSafeSelector(sel)) throw new Error('split capture/nth into two queries');","typeGuard":null,"tryCatchPattern":"try {\n  await page.$(sel);\n} catch (e) {\n  if (/chained selector with capture/.test(e.message)) {\n    const items = await page.$$(sel.replace(/\\s*nth\\s*=\\s*\\d+/, ''));\n    return items[1];\n  } else throw e;\n}","preventionTips":["Keep '*' capture and nth= in separate queries","Build chained selectors from tested helper functions, not ad-hoc concatenation","Prefer $$ plus array indexing over nth= inside chains"],"tags":["browser","selector","chained-selector","nth"],"backgroundTag":"chained-selector-capture","analyzedSha":"01ffac6f245854c1b8adc6a69857c76a15f90022","analyzedAt":"2026-08-18T03:05:52.393Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}