{"record":{"id":"73b0602d8dfc6912","repo":"grafana/k6","slug":"getting-properties-for-element-with-id-s-w","errorCode":null,"errorMessage":"getting properties for element with ID %s: %w","messagePattern":"getting properties for element with ID (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/js_handle.go","lineNumber":177,"sourceCode":"\thandles, err := h.getProperties()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tjsHandles := make(map[string]JSHandleAPI, len(handles))\n\tfor k, v := range handles {\n\t\tjsHandles[k] = v\n\t}\n\n\treturn jsHandles, nil\n}\n\n// getProperties is like GetProperties, but does not panic.\nfunc (h *BaseJSHandle) getProperties() (map[string]jsHandle, error) {\n\tact := runtime.GetProperties(h.remoteObject.ObjectID).WithOwnProperties(true)\n\tresult, _, _, _, err := act.Do(cdp.WithExecutor(h.ctx, h.session)) //nolint:dogsled\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"getting properties for element with ID %s: %w\",\n\t\t\th.remoteObject.ObjectID, err)\n\t}\n\n\tprops := make(map[string]jsHandle, len(result))\n\tfor _, r := range result {\n\t\tif !r.Enumerable {\n\t\t\tcontinue\n\t\t}\n\t\tprops[r.Name] = NewJSHandle(h.ctx, h.session, h.execCtx, h.execCtx.Frame(), r.Value, h.logger)\n\t}\n\n\treturn props, nil\n}\n\n// JSONValue returns a JSON version of this JS handle.\nfunc (h *BaseJSHandle) JSONValue() (string, error) {\n\tremoteObject := h.remoteObject\n\tif remoteObject.ObjectID != \"\" {","sourceCodeStart":159,"sourceCodeEnd":195,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/js_handle.go#L159-L195","documentation":"Thrown by BaseJSHandle.getProperties when the CDP Runtime.getProperties call fails for the handle's remote object ID. The remote object referenced by the handle no longer exists in the browser (it was disposed, garbage-collected, or its context was destroyed), so the DevTools protocol cannot enumerate its properties.","triggerScenarios":"Calling GetProperties() after handle.dispose() released the object; holding a handle across a navigation that destroyed its execution context; the browser garbage-collecting the JS object while the handle still references its ObjectID; the CDP session being closed mid-call.","commonSituations":"Caching handles globally in a long test instead of re-querying per iteration; disposing a handle then reusing it; page closing (browser.close or context.close) before the call completes.","solutions":["Never use a handle after calling dispose() on it; drop all references or re-query the element","Re-acquire the handle (page.$ / locator) immediately before GetProperties when navigation may have occurred","Check that the page and browser context are still open before calling","Wrap in try/catch and re-query the element once on failure"],"exampleFix":"// before\nconst h = await page.$('.cfg');\nawait h.dispose();\nconst props = await h.getProperties();   // object already released\n\n// after\nlet h = await page.$('.cfg');\nlet props;\ntry {\n  props = await h.getProperties();\n} catch (e) {\n  h = await page.$('.cfg');            // stale handle, re-acquire\n  props = await h.getProperties();\n}","handlingStrategy":"try-catch","validationCode":"if (page.isClosed()) throw new Error('page closed'); // disposed handles cannot be validated from JS — do not call dispose() before GetProperties","typeGuard":null,"tryCatchPattern":"try {\n  const props = await handle.getProperties();\n} catch (e) {\n  if (/getting properties for element/.test(e.message)) {\n    const fresh = await page.$(selector);\n    return fresh.getProperties(); // object ID was released/GC'd: re-acquire\n  }\n  throw e;\n}","preventionTips":["Never reuse a handle after dispose()","Query handles fresh in each iteration instead of caching","Avoid long gaps between element.$() and getProperties()"],"tags":["browser","cdp","js-handle","stale-reference","disposed-object"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}