{"record":{"id":"bfc40321cb3eebcb","repo":"grafana/k6","slug":"getting-frame-owner-w","errorCode":null,"errorMessage":"getting frame owner: %w","messagePattern":"getting frame owner: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/page.go","lineNumber":671,"sourceCode":"\t\treturn nil, errors.New(\"frame has been detached 1\")\n\t}\n\n\trootFrame := f\n\tfor ; rootFrame.parentFrame != nil; rootFrame = rootFrame.parentFrame {\n\t}\n\n\tparentSession, ok := p.getFrameSession(cdp.FrameID(rootFrame.ID()))\n\tif !ok {\n\t\treturn nil, errors.New(\"parent frame has been detached\")\n\t}\n\n\taction := dom.GetFrameOwner(cdp.FrameID(f.ID()))\n\tbackendNodeID, _, err := action.Do(cdp.WithExecutor(p.ctx, parentSession.session))\n\tif err != nil {\n\t\tif strings.Contains(err.Error(), \"frame with the given id was not found\") {\n\t\t\treturn nil, errors.New(\"frame has been detached\")\n\t\t}\n\t\treturn nil, fmt.Errorf(\"getting frame owner: %w\", err)\n\t}\n\n\tparent = f.parentFrame\n\tif parent == nil {\n\t\treturn nil, errors.New(\"frame has been detached 2\")\n\t}\n\treturn parent.adoptBackendNodeID(mainWorld, backendNodeID)\n}\n\nfunc (p *Page) getOwnerFrame(apiCtx context.Context, h *ElementHandle) (cdp.FrameID, error) {\n\tp.logger.Debugf(\"Page:getOwnerFrame\", \"sid:%v\", p.sessionID())\n\n\t// document.documentElement has frameId of the owner frame\n\tpageFn := `\n\t\tnode => {\n\t\t\tconst doc = node;\n      \t\tif (doc.documentElement && doc.documentElement.ownerDocument === doc)\n        \t\treturn doc.documentElement;","sourceCodeStart":653,"sourceCodeEnd":689,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/page.go#L653-L689","documentation":"Page.getFrameElement asked chromium (DOM.getFrameOwner) for the owner element of a frame and the CDP call failed with something other than the recognized 'frame with the given id was not found' message (which is mapped to a friendly 'frame has been detached' error). This happens while resolving frameElement() for an iframe — the parent session executed the query but chromium rejected it.","triggerScenarios":"Calling frameElement() (directly or via APIs that resolve an iframe's ElementHandle) when the frame tree is in flux: the iframe navigated and its old frame id is stale in a way that doesn't match the friendly error text, the parent frame session is mid-detach, or the page is closing so DOM.resolveNode-style follow-ups fail.","commonSituations":"Tests that grab content inside iframes while the outer page keeps navigating or redirecting; ad/widget iframes that destroy themselves mid-test; calling frameElement() on a frame whose parent already detached during teardown.","solutions":["Wait for the frame/iframe to be attached and stable (frame.waitForNavigation or waiting on a selector inside the frame) before frameElement()","Re-fetch the frame reference after navigations instead of caching it across goto/click","Do not call frame APIs once the page is closing; guard with page.isClosed()","If chromium's error text changed between versions, upgrade k6 so the friendly mapping keeps up — otherwise report it as a bug with the wrapped CDP error"],"exampleFix":"// before\nconst frame = page.frames()[1];\nconst el = await frame.frameElement(); // during iframe navigation\n\n// after\nawait page.waitForSelector('#myiframe >>> *'); // iframe content settled\nconst frame = page.frames().find(f => f.name === 'myiframe');\nconst el = await frame.frameElement();","handlingStrategy":"try-catch","validationCode":"if (page.isClosed()) { /* skip frameElement(): frame tree is going away */ }","typeGuard":null,"tryCatchPattern":"try {\n  const el = await frame.frameElement();\n} catch (e) {\n  const s = String(e);\n  if (/frame .*detached|getting frame owner/.test(s)) return null; // iframe churn\n  throw e;\n}","preventionTips":["Wait for iframe content to settle (waitForSelector inside the frame) before frameElement()","Re-acquire frame references after navigations; never cache across goto/click","Avoid frame APIs once page.isClosed() is true"],"tags":["cdp","browser","frames","iframe","race-condition"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}