grafana/k6 · error · InvalidSelectorError
Error while parsing selector
Error message
Error while parsing selector `${selector}` - cannot use ${operator} in attribute with regular expression What it means
Frame.FrameElement() (frame.go:990) returns the ElementHandle for a frame (the <iframe> or <frame> element in its parent document) via page.getFrameElement. The wrapper 'getting frame element' fires when that lookup fails: typically because the frame is already detached, its CDP session is gone, or resolving the frame owner through the DevTools protocol errored.
Solutions
- Re-acquire the frame right before use: const f = page.frames().find(fr => fr.name() === 'myframe'); then call f.frameElement().
- Do the call before triggering any action that can navigate or remove the iframe.
- Check page.frames() length/content to confirm the frame still exists.
- If the error appears after closing pages, restructure the script to finish iframe work before context/page close.
Example fix
// before
const f = page.frames()[2]; // captured earlier, iframe may be gone
const el = await f.frameElement();
// after
const f = page.frames().find(fr => fr.url().includes('/widget'));
if (!f) throw new Error('widget frame not attached');
const el = await f.frameElement(); Defensive patterns
Strategy: validation
Validate before calling
const f = page.frames().find(fr => fr.url().includes('/widget'));
if (!f) throw new Error('widget frame is not attached; cannot get frame element');
const el = await f.frameElement(); Try / catch
try {
return await frame.frameElement();
} catch (e) {
if (String(e).includes('getting frame element')) return null; // frame gone; caller re-discovers
throw e;
} Prevention
- Look frames up from page.frames() immediately before use instead of caching references.
- Finish iframe interactions before closing or navigating the parent page.
- Assert on the iframe's presence (by name/url) as an explicit step in the script.
When it happens
Trigger: The iframe was removed from the DOM or navigated away before the call; the frame's page was closed; the parent document changed so the frame's owner node no longer resolves; CDP session issues after browser/context crash.
Common situations: Scripts holding a stale Frame reference from page.frames() after the SPA replaced an iframe; ad or embed iframes that unload quickly; calling FrameElement during teardown after context.close().
Related errors
- frame not found for id
- frame has been detached
- Unexpected end of selector while parsing selector
- an error occurred communicating with k6 Cloud
- " " attribute is only supported for roles: "`).join(", ")}
AI-assisted analysis of grafana/k6@3fcf5388d7 (2026-08-18).
Data as JSON: /api/errors/1a9c9786a36ad5e9.
Report an issue: GitHub.
Appendix: source
Thrown at internal/js/modules/k6/browser/common/js/injected_script.js:1092
const jsonPath = [];
jsonPath.push(readAttributeToken());
skipSpaces();
while (next() === ".") {
eat1();
jsonPath.push(readAttributeToken());
skipSpaces();
}
if (next() === "]") {
eat1();
return { name: jsonPath.join("."), jsonPath, op: "<truthy>", value: null, caseSensitive: false };
}
const operator = readOperator();
let value = void 0;
let caseSensitive = true;
skipSpaces();
if (next() === "/") {
if (operator !== "=")
throw new InvalidSelectorError(`Error while parsing selector \`${selector}\` - cannot use ${operator} in attribute with regular expression`);
value = readRegularExpression();
} else if (next() === `'` || next() === `"`) {
value = readQuotedString(next()).slice(1, -1);
skipSpaces();
if (next() === "i" || next() === "I") {
caseSensitive = false;
eat1();
} else if (next() === "s" || next() === "S") {
caseSensitive = true;
eat1();
}
} else {
value = "";
while (!EOL && (isCSSNameChar(next()) || next() === "+" || next() === "."))
value += eat1();
if (value === "true") {
value = true;
} else if (value === "false") {View on GitHub (pinned to 3fcf5388d7)