grafana/k6 · error
getting attribute %q of element: %w
Error message
getting attribute %q of element: %w
What it means
Returned by ElementHandle.getAttribute(name) when the underlying evaluation fails. Internally the method evaluates element.getAttribute(name) via CDP with returnByValue; this error wraps a CDP/transport failure, a stale handle, or a timeout. Note that a missing attribute is NOT an error: in that case the method returns ("", false, nil) with no error.
Source
Thrown at internal/js/modules/k6/browser/common/element_handle.go:955
applySlowMo(h.ctx)
return nil
}
// GetAttribute retrieves the value of specified element attribute.
// The second return value is true if the attribute exists, and false otherwise.
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) {View on GitHub (pinned to 93accf6570)
Solutions
- Re-query the handle right before getAttribute instead of reusing an earlier page.$() result
- Wait for the element: page.waitForSelector(sel, { state: 'attached' })
- Call it after page.waitForLoadState() when a navigation just happened
- Increase the action timeout if the underlying error is a timeout
Example fix
// before
const h = await page.$('a.link');
const [href, ok] = await h.getAttribute('href');
// after
await page.waitForSelector('a.link', { state: 'attached' });
const h = await page.$('a.link');
const [href, ok] = await h.getAttribute('href'); Defensive patterns
Strategy: try-catch
Validate before calling
await page.waitForSelector('a.link', { state: 'attached' });
const h = await page.$('a.link');
const [href, ok] = await h.getAttribute('href');
if (!ok) { /* attribute absent: not an error */ } Try / catch
try {
const [v, ok] = await handle.getAttribute(name);
} catch (e) {
if (String(e).includes('getting attribute')) {
await page.waitForLoadState();
return (await page.$(sel)).getAttribute(name);
}
throw e;
} Prevention
- Remember: a missing attribute returns ok=false, not an error; an error means an operational failure
- Re-query handles before attribute reads in re-rendering pages
- Avoid mixing goto() with handles from the previous page
When it happens
Trigger: Calling getAttribute on a handle whose node was detached (SPA re-render) or that predates a navigation; calling it while the page is navigating (execution context destroyed); timeout expired while the action retried; browser/page closed mid-call.
Common situations: Reading data-* attributes from dynamically re-rendered lists where handles go stale; mixing goto() and old handles in the same iteration; CI runs where the browser is slow and default timeouts are tight.
Related errors
- focusing on element: %w
- getting element's inner HTML: %w
- getting element's inner text: %w
- filling element: %w
- hovering on element: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/fe554469cd26f126.
Report an issue: GitHub.