grafana/k6 · error · InvalidSelectorError

Error while parsing selector

Error message

Error while parsing selector `${selector}` - cannot use ${operator} in attribute with non-string matching value - ${value}

What it means

Frame.GetAttribute() (frame.go:1002) wraps the internal getAttribute action error with 'getting attribute %q of %q'. The action waits for an element matching the selector to attach within Timeout, then evaluates element.getAttribute(name) in the page. Failures wrapped here are selector/timeout failures (element not found, strict mode violation), detached frames, or evaluation errors from the page.

Solutions

  1. Wait for the element first: await page.waitForSelector(sel, { timeout: 10000 }) before GetAttribute.
  2. Query the correct frame: get the iframe's frame from page.frames() and call getAttribute on it.
  3. Double-check the attribute name and casing (SVG uses xlink:href style names).
  4. Raise the timeout explicitly if the element appears late: page.getAttribute(sel, name, { timeout: 60000 }).

Example fix

// before
const href = await page.getAttribute('a.details', 'href');

// after
const link = page.locator('a.details');
await link.waitFor({ state: 'attached', timeout: 10000 });
const href = await link.getAttribute('href');
Defensive patterns

Strategy: try-catch

Validate before calling

await page.waitForSelector('a.details', { state: 'attached', timeout: 5000 }); // element present before attribute read

Try / catch

try {
  return await page.getAttribute(sel, name, { timeout: 10000 });
} catch (e) {
  const msg = String(e);
  if (msg.includes('timed out')) return null; // element absent; treat as missing attribute
  throw e;
}

Prevention

When it happens

Trigger: Selector matches nothing before opts.Timeout expires; Strict:true with multiple matches; frame navigated/detached during resolution; the injected evaluation throws (e.g., page scripts overriding Element.prototype.getAttribute with a throwing getter).

Common situations: Reading href/value attributes of elements rendered after async data loads; attribute names with typos or wrong casing for SVG/XML documents; elements inside iframes queried on the wrong frame object.

Related errors


AI-assisted analysis of grafana/k6@3fcf5388d7 (2026-08-18). Data as JSON: /api/errors/42e4abdc533305f8. Report an issue: GitHub.

Appendix: source

Thrown at internal/js/modules/k6/browser/common/js/injected_script.js:1125

        value += eat1();
      if (value === "true") {
        value = true;
      } else if (value === "false") {
        value = false;
      } else {
        if (!allowUnquotedStrings) {
          value = +value;
          if (Number.isNaN(value))
            syntaxError("parsing attribute value");
        }
      }
    }
    skipSpaces();
    if (next() !== "]")
      syntaxError("parsing attribute value");
    eat1();
    if (operator !== "=" && typeof value !== "string")
      throw new InvalidSelectorError(`Error while parsing selector \`${selector}\` - cannot use ${operator} in attribute with non-string matching value - ${value}`);
    return { name: jsonPath.join("."), jsonPath, op: operator, value, caseSensitive };
  }
  const result = {
    name: "",
    attributes: []
  };
  result.name = readIdentifier();
  skipSpaces();
  while (next() === "[") {
    result.attributes.push(readAttribute());
    skipSpaces();
  }
  if (!EOL)
    syntaxError(void 0);
  if (!result.name && !result.attributes.length)
    throw new InvalidSelectorError(`Error while parsing selector \`${selector}\` - selector cannot be empty`);
  return result;
}

View on GitHub (pinned to 3fcf5388d7)