grafana/k6 · error
can't query n-th element in a chained selector with capture
Error message
can't query n-th element in a chained selector with capture
What it means
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.
Source
Thrown at internal/js/modules/k6/browser/common/element_handle.go:1915
"error:notelement": "node is not an element",
"error:nothtmlelement": "not an HTMLElement",
"error:notfillableelement": "element is not an <input>, <textarea> or [contenteditable] element",
"error:notfillableinputtype": "input of this type cannot be filled",
"error:notfillablenumberinput": "cannot type text into input[type=number]",
"error:notvaliddate": "malformed value",
"error:notinput": "node is not an HTMLInputElement",
"error:notfile": "node is not an input[type=file] element",
"error:hasnovalue": "node is not an HTMLInputElement or HTMLTextAreaElement or HTMLSelectElement",
"error:notselect": "element is not a <select> element",
"error:notcheckbox": "not a checkbox or radio button",
"error:notmultiplefileinput": "non-multiple file input can only accept single file",
"error:strictmodeviolation": "strict mode violation, multiple elements returned for selector query",
"error:notqueryablenode": "node is not queryable",
"error:nthnocapture": "can't query n-th element in a chained selector with capture",
"error:intercept": "another element is intercepting with pointer action",
}
if err, ok := errs[serr]; ok {
return errors.New(err)
}
return errors.New(serr)
}
View on GitHub (pinned to 01ffac6f24)
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
Example fix
// before
const el = await page.$('*css=div.item >> nth=1'); // nth with capture
// after
const items = await page.$$('css=div.item');
const el = items[1]; Defensive patterns
Strategy: validation
Validate before calling
// Reject capture+nth chains before using them
function isSafeSelector(sel) {
const parts = sel.split('>>');
const hasCapture = parts.some(p => p.trim().startsWith('*'));
const hasNth = parts.some(p => /nth\s*=/.test(p));
return !(hasCapture && hasNth);
}
if (!isSafeSelector(sel)) throw new Error('split capture/nth into two queries'); Try / catch
try {
await page.$(sel);
} catch (e) {
if (/chained selector with capture/.test(e.message)) {
const items = await page.$$(sel.replace(/\s*nth\s*=\s*\d+/, ''));
return items[1];
} else throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: Building selectors programmatically by concatenating fragments; porting Playwright locator chains (locator.nth()) into k6 chained selector strings.
Related errors
- only one of the selectors can capture using * modifier
- Error while parsing selector `${selector}` - unexpected symb
- Error while parsing selector `${selector}`: ${e.message}
- Error while parsing selector `${selector}` - cannot use ${op
- "${attr.name}" does not support "${attr.op}" matcher
AI-assisted analysis of grafana/k6@01ffac6f24 (2026-08-18).
Data as JSON: /api/errors/924689166d95ae6b.
Report an issue: GitHub.