{"record":{"id":"6a0abe55c66507ca","repo":"microsoft/playwright","slug":"frame-has-been-detached-6a0abe","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/webview/wvPage.ts","lineNumber":1000,"sourceCode":"    }\n    return path;\n  }\n\n  private async _childFrameAndDispose(progress: Progress, iframe: dom.ElementHandle): Promise<frames.Frame | null> {\n    try {\n      return await progress.race(this.getContentFrame(iframe));\n    } finally {\n      iframe.dispose();\n    }\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    // Requesting the frame's own document streams its ancestor path, which\n    // includes the owner element (and its siblings). Pick the one whose\n    // contentDocument is this frame, then resolve it in the parent's context.\n    const documentHandle = await (await frame.mainContext()).evaluateHandle(() => document);\n    let ownerNodeId: number | undefined;\n    try {\n      if (documentHandle._objectId) {\n        const { nodesById } = await this._requestNodeViaDOM(documentHandle._objectId);\n        for (const node of nodesById.values()) {\n          if (node.contentDocument?.frameId === frame._id) {\n            ownerNodeId = node.nodeId;\n            break;\n          }\n        }\n      }\n    } finally {\n      documentHandle.dispose();\n    }","sourceCodeStart":982,"sourceCodeEnd":1018,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/server/webkit/webview/wvPage.ts#L982-L1018","documentation":"Thrown by getFrameElement() in the webview backend when frame.parentFrame() returns null. A Frame with no parent is either a top-level main frame or a frame whose parent has already been detached/destroyed. Since getFrameElement's job is to find the <iframe>/<frame> element in the parent document, a missing parent makes the operation meaningless.","triggerScenarios":"Calling frame.frameElement() (or any internal code that resolves a frame's owner element) on the main frame, or on an iframe whose parent frame was removed from the DOM before the call resolves. Also reachable during cross-frame quad/pointer math that walks frame trees in wvPage.","commonSituations":"Holding a stale Frame reference after the iframe element was removed. Calling frameElement() on page.mainFrame(). Race between iframe detach and a snapshot/locator operation running on the webview transport.","solutions":["Guard with frame.parentFrame() before calling frame.frameElement(); skip or no-op for the main frame.","Check frame.isDetached() and short-circuit before resolving the owner element.","Refresh the Frame reference from page.frames() after navigation/iframe removal and retry on the fresh instance."],"exampleFix":"// before\nconst el = await frame.frameElement();\n\n// after\nif (frame.isDetached() || !frame.parentFrame()) return null;\nconst el = await frame.frameElement();","handlingStrategy":"validation","validationCode":"function canGetFrameElement(frame) {\n  return !!frame.parentFrame() && !frame.isDetached();\n}\n// usage\nif (canGetFrameElement(frame)) await frame.frameElement();","typeGuard":"function hasParentFrame(frame: any): frame is import('playwright-core').Frame {\n  return !!frame && typeof frame.parentFrame === 'function' && !!frame.parentFrame();\n}","tryCatchPattern":"try { return await frame.frameElement(); }\ncatch (e) {\n  if ((e as Error).message === 'Frame has been detached.') return null;\n  throw e;\n}","preventionTips":["Never call frameElement() on page.mainFrame().","Re-acquire Frame references from page.frames() after navigation/iframe removal."],"tags":["webkit","webview","frames","detached"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}