{"record":{"id":"d3e0f6a840123157","repo":"microsoft/playwright","slug":"frame-has-been-detached-d3e0f6","errorCode":null,"errorMessage":"Frame has been detached.","messagePattern":"Frame has been detached\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/server/webkit/wkPage.ts","lineNumber":1018,"sourceCode":"    const result = await this._session.sendMayFail('DOM.resolveNode', {\n      objectId: handle._objectId,\n      executionContextId: (to.delegate as WKExecutionContext)._contextId\n    });\n    if (!result || result.object.subtype === 'null')\n      throw new Error(dom.kUnableToAdoptErrorMessage);\n    return createHandle(to, result.object) as dom.ElementHandle<T>;\n  }\n\n  async inputActionEpilogue(): Promise<void> {\n  }\n\n  async resetForReuse(progress: Progress): Promise<void> {\n  }\n\n  async getFrameElement(frame: frames.Frame): Promise<dom.ElementHandle> {\n    const parent = frame.parentFrame();\n    if (!parent)\n      throw new Error('Frame has been detached.');\n    const context = await parent.mainContext();\n    const result = await this._session.send('DOM.resolveNode', {\n      frameId: frame._id,\n      executionContextId: (context.delegate as WKExecutionContext)._contextId\n    });\n    if (!result || result.object.subtype === 'null')\n      throw new Error('Frame has been detached.');\n    return createHandle(context, result.object) as dom.ElementHandle;\n  }\n\n  private _maybeCancelCoopNavigationRequest(provisionalPage: WKProvisionalPage) {\n    const navigationRequest = provisionalPage.coopNavigationRequest();\n    for (const [requestId, request] of this._requestIdToRequest) {\n      if (request.request === navigationRequest) {\n        // Make sure the request completes if the provisional navigation is canceled.\n        this._onLoadingFailed(provisionalPage._session, {\n          requestId: requestId,\n          errorText: 'Provisiolal navigation canceled.',","sourceCodeStart":1000,"sourceCodeEnd":1036,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/server/webkit/wkPage.ts#L1000-L1036","documentation":"getFrameElement() throws when frame.parentFrame() is null — the frame is the main frame or has no living parent. Without a parent document there is no owner <iframe> element to resolve, so the operation is undefined. Mirrors the wvPage variant but on the standard WKPage backend.","triggerScenarios":"Calling frame.frameElement() (or internal getFrameElement) on page.mainFrame() or on a frame whose parent was detached. Any snapshot/locator path that resolves a frame's owner element.","commonSituations":"Calling frameElement() on the top frame. Holding a stale child Frame after the parent removed it. Race between detach and an owner-element resolution.","solutions":["Guard with frame.parentFrame() and frame.isDetached() before calling frame.frameElement().","Skip owner-element resolution for the main frame entirely.","Re-acquire frames from page.frames() after navigation."],"exampleFix":"// before\nconst el = await frame.frameElement();\n\n// after\nif (!frame.parentFrame() || frame.isDetached()) return null;\nconst el = await frame.frameElement();","handlingStrategy":"validation","validationCode":"function canGetOwner(frame) { return !!frame.parentFrame() && !frame.isDetached(); }\nif (canGetOwner(frame)) await frame.frameElement();","typeGuard":"function hasLivingParent(frame: any): boolean { return !!frame?.parentFrame() && !frame.isDetached(); }","tryCatchPattern":"try { return await frame.frameElement(); }\ncatch (e) { if (/Frame has been detached/.test(e.message)) return null; throw e; }","preventionTips":["Skip frameElement() on the main frame.","Check isDetached() before resolving owner elements."],"tags":["webkit","frames","detached","owner-element"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}