{"record":{"id":"5d86bf90cd4ca06d","repo":"grafana/k6","slug":"getting-remote-node-q-w","errorCode":null,"errorMessage":"getting remote node %q: %w","messagePattern":"getting remote node %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/element_handle.go","lineNumber":859,"sourceCode":"\t\t&opts.ElementHandleBasePointerOptions,\n\t)\n\tif _, err := call(h.ctx, click, opts.Timeout); err != nil {\n\t\treturn fmt.Errorf(\"clicking on element: %w\", err)\n\t}\n\tapplySlowMo(h.ctx)\n\n\treturn nil\n}\n\n// ContentFrame returns the frame that contains this element.\nfunc (h *ElementHandle) ContentFrame() (*Frame, error) {\n\tvar (\n\t\tnode *cdp.Node\n\t\terr  error\n\t)\n\taction := dom.DescribeNode().WithObjectID(h.remoteObject.ObjectID)\n\tif node, err = action.Do(cdp.WithExecutor(h.ctx, h.session)); err != nil {\n\t\treturn nil, fmt.Errorf(\"getting remote node %q: %w\", h.remoteObject.ObjectID, err)\n\t}\n\tif node == nil || node.FrameID == \"\" {\n\t\treturn nil, fmt.Errorf(\"element is not an iframe\")\n\t}\n\n\tframe, ok := h.frame.manager.getFrameByID(node.FrameID)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"frame not found for id %s\", node.FrameID)\n\t}\n\n\treturn frame, nil\n}\n\n// Dblclick scrolls element into view and double clicks on the element.\nfunc (h *ElementHandle) Dblclick(opts *ElementHandleDblclickOptions) error {\n\tdblclick := func(_ context.Context, handle *ElementHandle, p *Position) (any, error) {\n\t\treturn nil, handle.dblclick(p, opts.ToMouseClickOptions())\n\t}","sourceCodeStart":841,"sourceCodeEnd":877,"githubUrl":"https://github.com/grafana/k6/blob/3fcf5388d78cb382f0c0d42ec556a06bfd1b8dee/internal/js/modules/k6/browser/common/element_handle.go#L841-L877","documentation":"ContentFrame() starts with a CDP dom.DescribeNode call for the element's remote object; this error wraps that protocol call failing. The remote object ID became unusable — the element was removed by a navigation/re-render, the execution context was destroyed, or the browser session/target is gone.","triggerScenarios":"Calling contentFrame() (or frame-chained selectors that step into iframes) on a handle whose node no longer exists: the page navigated after the handle was created, an SPA re-rendered the iframe away, or the renderer/session died; DescribeNode rejects the stale ObjectID.","commonSituations":"Holding element handles across page.goto or SPA route changes; iframes recreated by frameworks on each render; remote/cloud browsers dropping sessions; timing races right after load events.","solutions":["Re-query the element immediately before calling contentFrame() — do not cache handles across navigations","Wait for the page/frame to settle: await page.waitForLoadState('load') before resolving the iframe element","On failure, retry the whole query-and-step-in sequence once after a short wait","Verify the session is alive (page.isClosed()) and restart the iteration if the browser crashed"],"exampleFix":"// before\nconst el = await page.$('iframe#app');\nawait page.reload();\nconst frame = await el.contentFrame(); // stale\n\n// after\nawait page.reload();\nconst el = await page.$('iframe#app');\nconst frame = await el.contentFrame();","handlingStrategy":"retry","validationCode":"if (page.isClosed()) throw new Error('page closed; stale handle unusable');\nawait page.waitForLoadState('load');\nconst el = await page.$('iframe#app'); // fresh handle after navigation","typeGuard":null,"tryCatchPattern":"let frame;\nfor (let attempt = 0; attempt < 2; attempt++) {\n  try {\n    frame = await el.contentFrame();\n    break;\n  } catch (e) {\n    if (attempt === 1 || page.isClosed()) throw e;\n    await page.waitForTimeout(500);\n    el = await page.$('iframe#app'); // re-acquire\n  }\n}","preventionTips":["Re-query iframe elements after every navigation or SPA route change","Wait for load state before resolving elements you plan to step into","Treat DescribeNode failures as staleness: refresh the handle, don't retry the stale one"],"tags":["browser","iframe","cdp","stale-element","dom-describe-node"],"backgroundTag":"stale-element-reference","analyzedSha":"3fcf5388d78cb382f0c0d42ec556a06bfd1b8dee","analyzedAt":"2026-08-18T03:05:52.393Z","contentChangedAt":"2026-08-18T03:05:52.393Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}