{"record":{"id":"fe554469cd26f126","repo":"grafana/k6","slug":"getting-attribute-q-of-element-w","errorCode":null,"errorMessage":"getting attribute %q of element: %w","messagePattern":"getting attribute %q of element: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/element_handle.go","lineNumber":955,"sourceCode":"\tapplySlowMo(h.ctx)\n\n\treturn nil\n}\n\n// GetAttribute retrieves the value of specified element attribute.\n// The second return value is true if the attribute exists, and false otherwise.\nfunc (h *ElementHandle) GetAttribute(name string) (string, bool, error) {\n\tgetAttribute := func(apiCtx context.Context, handle *ElementHandle) (any, error) {\n\t\treturn handle.getAttribute(apiCtx, name)\n\t}\n\topts := NewElementHandleBaseOptions(h.DefaultTimeout())\n\tgetAttributeAction := h.newAction(\n\t\t[]string{}, getAttribute, opts.Force, withRetry, opts.NoWaitAfter, opts.Timeout,\n\t)\n\n\tv, err := call(h.ctx, getAttributeAction, opts.Timeout)\n\tif err != nil {\n\t\treturn \"\", false, fmt.Errorf(\"getting attribute %q of element: %w\", name, err)\n\t}\n\tif v == nil {\n\t\treturn \"\", false, nil\n\t}\n\ts, ok := v.(string)\n\tif !ok {\n\t\treturn \"\", false, fmt.Errorf(\n\t\t\t\"getting attribute %q of element: unexpected type %T (expecting string)\",\n\t\t\tname, v,\n\t\t)\n\t}\n\n\treturn s, true, nil\n}\n\n// Hover scrolls element into view and hovers over its center point.\nfunc (h *ElementHandle) Hover(opts *ElementHandleHoverOptions) error {\n\thover := func(apiCtx context.Context, handle *ElementHandle, p *Position) (any, error) {","sourceCodeStart":937,"sourceCodeEnd":973,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/element_handle.go#L937-L973","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nconst h = await page.$('a.link');\nconst [href, ok] = await h.getAttribute('href');\n// after\nawait page.waitForSelector('a.link', { state: 'attached' });\nconst h = await page.$('a.link');\nconst [href, ok] = await h.getAttribute('href');","handlingStrategy":"try-catch","validationCode":"await page.waitForSelector('a.link', { state: 'attached' });\nconst h = await page.$('a.link');\nconst [href, ok] = await h.getAttribute('href');\nif (!ok) { /* attribute absent: not an error */ }","typeGuard":null,"tryCatchPattern":"try {\n  const [v, ok] = await handle.getAttribute(name);\n} catch (e) {\n  if (String(e).includes('getting attribute')) {\n    await page.waitForLoadState();\n    return (await page.$(sel)).getAttribute(name);\n  }\n  throw e;\n}","preventionTips":["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"],"tags":["browser","element-handle","get-attribute","detached-handle","timeout"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}