{"record":{"id":"a1a9ec85d38a6b6e","repo":"microsoft/playwright","slug":"frame-was-detached","errorCode":null,"errorMessage":"Frame was detached","messagePattern":"Frame was detached","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/playwright-core/src/server/frames.ts","lineNumber":795,"sourceCode":"  }\n\n  async waitForLoadState(progress: Progress, state: types.LifecycleEvent): Promise<void> {\n    const waitUntil = verifyLifecycle('state', state);\n    if (!this._firedLifecycleEvents.has(waitUntil))\n      await helper.waitForEvent(progress, this, Frame.Events.AddLifecycle, (e: types.LifecycleEvent) => e === waitUntil).promise;\n  }\n\n  async frameElement(progress: Progress): Promise<dom.ElementHandle> {\n    return await progress.race(this._page.delegate.getFrameElement(this));\n  }\n\n  context(world: types.World): Promise<dom.FrameExecutionContext> {\n    if (this._page.delegate.noUtilityWorld?.())\n      world = 'main';\n    return this._contextData.get(world)!.contextPromise.then(contextOrDestroyedReason => {\n      if (contextOrDestroyedReason instanceof js.ExecutionContext)\n        return contextOrDestroyedReason;\n      throw new Error(contextOrDestroyedReason.destroyedReason);\n    });\n  }\n\n  mainContext(): Promise<dom.FrameExecutionContext> {\n    return this.context('main');\n  }\n\n  existingContext(world: types.World): dom.FrameExecutionContext | null {\n    if (this._page.delegate.noUtilityWorld?.())\n      world = 'main';\n    return this._contextData.get(world)?.context || null;\n  }\n\n  utilityContext(): Promise<dom.FrameExecutionContext> {\n    return this.context('utility');\n  }\n\n  async evaluateExpression(progress: Progress, expression: string, options: { isFunction?: boolean, world?: types.World } = {}, arg?: any): Promise<any> {","sourceCodeStart":777,"sourceCodeEnd":813,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/server/frames.ts#L777-L813","documentation":"frame.context(world) awaits the world's contextPromise. If the promise resolves to a destroyed marker (not an ExecutionContext) - because the frame was detached/destroyed - it throws the stored destroyedReason, conventionally 'Frame was detached'.","triggerScenarios":"Requesting a frame's execution context after the frame has been detached from the DOM (removed iframe, closed popup window, navigation that destroyed the frame).","commonSituations":"Holding a Frame reference and using it after the iframe was removed from the page; acting on popup windows after they closed; operations scheduled on a frame that detached between scheduling and execution.","solutions":["Drop stale Frame references; re-query page.frame(...) or page.mainFrame() as needed.","Guard operations by checking the frame still exists in page.frames().","Await the action that removes the iframe only after you are done with the frame.","Listen for the frameDetached event and cancel pending work."],"exampleFix":"// before\nconst frame = page.frame({ name: 'widget' });\nawait removeIframe();\nawait frame.evaluate(() => 1); // throws 'Frame was detached'\n// after\nconst frame = page.frame({ name: 'widget' });\nawait frame.evaluate(() => 1);\nawait removeIframe();","handlingStrategy":"validation","validationCode":"// Verify the frame is still attached before use\nif (!page.frames().includes(frame)) throw new Error('frame detached');\nawait frame.evaluate(() => 1);","typeGuard":"function isFrameAlive(page: any, frame: any): boolean {\n  return page.frames().includes(frame);\n}","tryCatchPattern":"try {\n  await frame.evaluate(fn);\n} catch (e) {\n  if (e instanceof Error && /Frame was detached|Target frame/i.test(e.message)) { /* re-acquire */ }\n  else throw e;\n}","preventionTips":["Never retain a Frame reference across DOM operations that remove its iframe.","Re-query frames by name/url at the point of use."],"tags":["frames","detached","lifecycle"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}