grafana/k6 · error

Unknown attribute "${attr.name}", must be one of ${kSupporte

Error message

Unknown attribute "${attr.name}", must be one of ${kSupportedAttributes.map((a) => `"${a}"`).join(", ")}.

What it means

Frame.InputValue() (frame.go:1365) wraps the inputValue action failure as 'getting input value of %q'. The action waits for a selector match in the attached state within Timeout and evaluates element.value, but the injected JS first rejects nodes that are not <input>, <textarea>, or <select> (it throws 'Node is not an <input>, <textarea> or <select> element'). So the wrapped error is a selector timeout, strict violation, frame/context failure, or a wrong-element-type failure.

Source

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

      }
      case "name": {
        if (attr.op === "<truthy>")
          throw new Error(`"name" attribute must have a value`);
        if (typeof attr.value !== "string" && !(attr.value instanceof RegExp))
          throw new Error(`"name" attribute must be a string or a regular expression`);
        options.name = attr.value;
        options.nameOp = attr.op;
        options.exact = attr.caseSensitive;
        break;
      }
      case "include-hidden": {
        validateSupportedValues(attr, [true, false]);
        validateSupportedOp(attr, ["<truthy>", "="]);
        options.includeHidden = attr.op === "<truthy>" ? true : attr.value;
        break;
      }
      default: {
        throw new Error(`Unknown attribute "${attr.name}", must be one of ${kSupportedAttributes.map((a) => `"${a}"`).join(", ")}.`);
      }
    }
  }
  return options;
}
function queryRole(scope, options, internal) {
  const result = [];
  const match = (element) => {
    if (getAriaRole(element) !== options.role)
      return;
    if (options.selected !== void 0 && getAriaSelected(element) !== options.selected)
      return;
    if (options.checked !== void 0 && getAriaChecked(element) !== options.checked)
      return;
    if (options.pressed !== void 0 && getAriaPressed(element) !== options.pressed)
      return;
    if (options.expanded !== void 0 && getAriaExpanded(element) !== options.expanded)
      return;

View on GitHub (pinned to 01ffac6f24)

Solutions

  1. Confirm the target is a real input/textarea/select: check the page markup or use page.evaluate to log document.querySelector(sel).tagName.
  2. Wait for the element first: await page.waitForSelector(sel, { timeout: 10000 }).
  3. For custom widgets, read the underlying hidden input's value or the widget's state via page.evaluate.
  4. Call InputValue on the frame that owns the element.

Example fix

// before
const v = await page.inputValue('#combo'); // div widget -> error

// after
const v = await page.evaluate(`
  document.querySelector('#combo input')?.value ?? ''
`);
Defensive patterns

Strategy: try-catch

Validate before calling

const tag = await page.evaluate(`
  document.querySelector(sel)?.tagName ?? 'none'
`);
if (!['INPUT', 'TEXTAREA', 'SELECT'].includes(tag)) throw new Error(`${tag} has no input value`);

Try / catch

try {
  return await page.inputValue(sel, { timeout: 10000 });
} catch (e) {
  const msg = String(e);
  if (msg.includes('input') && msg.includes('element')) return null; // wrong element type
  if (msg.includes('timed out')) return null; // element absent
  throw e;
}

Prevention

When it happens

Trigger: Selector matches nothing before Timeout; multiple matches with Strict:true; the matched element is a div/span/custom widget rather than a real input control; the frame navigates during the read.

Common situations: Reading values from custom comboboxes/autocomplete widgets built from divs; reading before the app populates the field; querying the main frame for a control inside an iframe.

Related errors


AI-assisted analysis of grafana/k6@01ffac6f24 (2026-08-18). Data as JSON: /api/errors/79eba78b87c16101. Report an issue: GitHub.