grafana/k6 · error
getting attribute of element: unexpected type %T (expecting…
Error message
getting attribute %q of element: unexpected type %T (expecting string)
What it means
After the CDP evaluation for ElementHandle.getAttribute() succeeds, a non-nil result that is not a Go string triggers this invariant error. A missing attribute returns JS null (handled earlier as found=false), so this fires only when the page returns some other type - typically because page scripts monkey-patched Element.prototype.getAttribute, or the evaluation returned undefined for an unusual node.
Solutions
- Read the attribute through raw evaluation: await el.evaluate((e, n) => e.getAttribute(n), name)
- Check whether the page patches DOM APIs: await el.evaluate(() => Element.prototype.getAttribute.toString())
- If the page is stock and the error reproduces, report it as a bug to the k6-browser repository with a minimal repro
Example fix
// before
const v = await el.getAttribute('data-id'); // unexpected type error
// after
let v;
try {
v = await el.getAttribute('data-id');
} catch (e) {
v = await el.evaluate((el2, n) => el2.getAttribute(n), 'data-id');
} Defensive patterns
Strategy: validation
Validate before calling
// Detect DOM API tampering before relying on getAttribute
const patched = await el.evaluate(
() => Element.prototype.getAttribute.toString().includes('[native code]') === false
);
if (patched) {
const v = await el.evaluate((e, n) => e.getAttribute(n), name);
} else {
const v = await el.getAttribute(name);
} Try / catch
try {
const v = await el.getAttribute(name);
} catch (e) {
if (/unexpected type/i.test(String(e.message))) {
const v = await el.evaluate((e2, n) => e2.getAttribute(n), name); // raw read
} else throw e;
} Prevention
- Suspect DOM patching when testing bot-protected or heavily instrumented pages
- Use el.evaluate() for attribute reads on pages that override DOM prototypes
- Report reproducible cases with unmodified pages to the k6-browser maintainers
When it happens
Trigger: Anti-bot/instrumentation scripts (bot detection, RUM tools) overriding getAttribute on the page; the handle resolved to a non-element node where getAttribute is undefined; a compromised or exotic DOM returned by the page under test.
Common situations: Testing pages protected by bot-detection services that patch DOM APIs; unusual shadow-DOM or namespaced nodes; essentially an internal invariant violation that almost never fires on stock pages.
Related errors
- getting attribute of element
- unexpected type %T (expecting string)
- an error occurred communicating with the provisioning API
- checking is in viewport: unexpected type %T
- converting result ( of type %t) to size
AI-assisted analysis of grafana/k6@3fcf5388d7 (2026-08-18).
Data as JSON: /api/errors/a5d107e2af88d02e.
Report an issue: GitHub.
Appendix: source
Thrown at internal/js/modules/k6/browser/common/element_handle.go:962
func (h *ElementHandle) GetAttribute(name string) (string, bool, error) {
getAttribute := func(apiCtx context.Context, handle *ElementHandle) (any, error) {
return handle.getAttribute(apiCtx, name)
}
opts := NewElementHandleBaseOptions(h.DefaultTimeout())
getAttributeAction := h.newAction(
[]string{}, getAttribute, opts.Force, withRetry, opts.NoWaitAfter, opts.Timeout,
)
v, err := call(h.ctx, getAttributeAction, opts.Timeout)
if err != nil {
return "", false, fmt.Errorf("getting attribute %q of element: %w", name, err)
}
if v == nil {
return "", false, nil
}
s, ok := v.(string)
if !ok {
return "", false, fmt.Errorf(
"getting attribute %q of element: unexpected type %T (expecting string)",
name, v,
)
}
return s, true, nil
}
// Hover scrolls element into view and hovers over its center point.
func (h *ElementHandle) Hover(opts *ElementHandleHoverOptions) error {
hover := func(apiCtx context.Context, handle *ElementHandle, p *Position) (any, error) {
return nil, handle.hover(apiCtx, p)
}
hoverAction := h.newPointerAction(hover, &opts.ElementHandleBasePointerOptions)
if _, err := call(h.ctx, hoverAction, opts.Timeout); err != nil {
return fmt.Errorf("hovering on element: %w", err)
}
View on GitHub (pinned to 3fcf5388d7)