{"record":{"id":"5b5cd6c4a466029e","repo":"grafana/k6","slug":"frame-not-found-for-id-s","errorCode":null,"errorMessage":"frame not found for id %s","messagePattern":"frame not found for id (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/element_handle.go","lineNumber":867,"sourceCode":"}\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}\n\tdblclickAction := h.newPointerAction(dblclick, &opts.ElementHandleBasePointerOptions)\n\tif _, err := call(h.ctx, dblclickAction, opts.Timeout); err != nil {\n\t\treturn fmt.Errorf(\"double clicking on element: %w\", err)\n\t}\n\n\tapplySlowMo(h.ctx)\n\n\treturn nil","sourceCodeStart":849,"sourceCodeEnd":885,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/element_handle.go#L849-L885","documentation":"ContentFrame() resolved a FrameID from the DOM node, but the page's frame manager has no registered frame with that ID. The iframe was detached or navigated away, or its frame-tree entry was never attached (out-of-process iframe attach race).","triggerScenarios":"contentFrame() (directly or via frame-crossing selectors) on an iframe being removed/replaced at that instant, a cross-origin iframe whose OOP frame is not yet attached, or right after the iframe's src changed.","commonSituations":"Ad iframes swapping in and out; SPA re-renders replacing iframes; querying inside an iframe immediately after load before the frame tree settles.","solutions":["Retry after a short wait — frame attachment is often just racing","Wait for a known selector inside the iframe instead of grabbing the frame directly","Prefer page.frameLocator(), which re-resolves the frame chain on each action","Increase the timeout so iframe attachment completes"],"exampleFix":"// before\nconst frame = await (await page.$('#lateframe')).contentFrame(); // frame not found for id ...\n\n// after\nawait page.waitForSelector('#lateframe >> .ready');\nconst frame = await (await page.$('#lateframe')).contentFrame();","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"async function getContentFrame(page, sel, tries = 3) {\n  for (let i = 0; i < tries; i++) {\n    try { return await (await page.$(sel)).contentFrame(); }\n    catch (e) {\n      if (!String(e).includes('frame not found')) throw e;\n      await sleep(500); // frame tree still attaching\n    }\n  }\n  throw new Error('iframe frame never attached');\n}","preventionTips":["Wait for a selector inside the iframe before using its frame","Expect attach races right after load and after src swaps","Prefer frameLocator(), which re-resolves per action"],"tags":["browser","iframe","race-condition","frame-tree"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}