{"record":{"id":"dca7cfc96f2fd64b","repo":"ionic-team/ionic-framework","slug":"inserted-view-was-already-inserted","errorCode":null,"errorMessage":"inserted view was already inserted","messagePattern":"inserted view was already inserted","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"core/src/components/nav/nav.tsx","lineNumber":739,"sourceCode":"    }\n\n    const insertViews = ti.insertViews;\n    if (!insertViews) {\n      return;\n    }\n    assert(insertViews.length > 0, 'length can not be zero');\n    const viewControllers = convertToViews(insertViews);\n\n    if (viewControllers.length === 0) {\n      throw new Error('invalid views to insert');\n    }\n\n    // Check all the inserted view are correct\n    for (const view of viewControllers) {\n      view.delegate = ti.opts.delegate;\n      const nav = view.nav;\n      if (nav && nav !== this) {\n        throw new Error('inserted view was already inserted');\n      }\n      if (view.state === VIEW_STATE_DESTROYED) {\n        throw new Error('inserted view was already destroyed');\n      }\n    }\n    ti.insertViews = viewControllers;\n  }\n\n  /**\n   * Returns the view that will be entered considering the transition instructions.\n   *\n   * @param ti The instructions.\n   * @param leavingView The view being left or undefined if none.\n   *\n   * @returns The view that will be entered, undefined if none.\n   */\n  private getEnteringView(\n    ti: TransitionInstruction,","sourceCodeStart":721,"sourceCodeEnd":757,"githubUrl":"https://github.com/ionic-team/ionic-framework/blob/625f9c38ad8c5db8a6c12df5c1622a36da90f9e3/core/src/components/nav/nav.tsx#L721-L757","documentation":"Thrown in IonNav.prepareTI() while validating each inserted view: a view being inserted already has `view.nav` set to a different nav instance. Views track which nav owns them; inserting a view that another nav already claims would corrupt both stacks, so the nav rejects it.","triggerScenarios":"Passing a ViewController to `insert`/`push`/`setPages` that was obtained from another IonNav (e.g. via `nav.getActive()` on a sibling) without detaching it first; reusing a live ViewController instance across two navs.","commonSituations":"Sharing a view reference between a parent and child IonNav; manually constructing/obtaining a ViewController and pushing it into a second nav; advanced nested-nav setups that move views between stacks.","solutions":["Do not pass live ViewController instances between navs; pass the underlying component and let the target nav create a fresh view.","If you genuinely need to move a view, pop it from the source nav first and then insert the component (not the controller) into the target.","Use `nav.getByIndex`/`getActive` only to read state, never to relocate the controller into another nav.","Audit code that calls `insert`/`insertPages` for any controller obtained from `getViews()`/`getActive()`."],"exampleFix":"// before\nconst view = otherNav.getActive();\nawait thisNav.insert(0, view);\n// after\nconst { component, componentProps } = view;\nawait otherNav.removeIndex(otherNav.getViews().indexOf(view), 1);\nawait thisNav.insert(0, component, componentProps);","handlingStrategy":"validation","validationCode":"// Never pass a live controller to another nav; insert the component instead\nif (viewController.nav && viewController.nav !== nav) {\n  throw new Error('View already belongs to another nav. Insert its component instead.');\n}\nawait nav.insert(0, viewController.component, viewController.componentProps);","typeGuard":"function isOwnedBy(view: ViewController, nav: HTMLIonNavElement): boolean {\n  return !view.nav || view.nav === nav;\n}","tryCatchPattern":null,"preventionTips":["Pass component references, not ViewController instances, when moving between navs.","Treat getActive()/getByIndex() results as read-only; do not relocate them.","Audit nested-nav code for any controller sharing."],"tags":["core","ion-nav","navigation","view-controller"],"backgroundTag":null,"analyzedSha":"625f9c38ad8c5db8a6c12df5c1622a36da90f9e3","analyzedAt":"2026-08-12T16:00:25.413Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}