{"record":{"id":"3afdf01052fd8655","repo":"ionic-team/ionic-framework","slug":"cannot-activate-an-already-activated-outlet","errorCode":null,"errorMessage":"Cannot activate an already activated outlet","messagePattern":"Cannot activate an already activated outlet","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/angular/common/src/directives/navigation/router-outlet.ts","lineNumber":243,"sourceCode":"        this.activatedView.savedExtras = {};\n        if (context.route) {\n          const contextSnapshot = context.route.snapshot;\n\n          this.activatedView.savedExtras.queryParams = contextSnapshot.queryParams;\n          (this.activatedView.savedExtras.fragment as string | null) = contextSnapshot.fragment;\n        }\n      }\n      const c = this.component;\n      this.activatedView = null;\n      this.activated = null;\n      this._activatedRoute = null;\n      this.deactivateEvents.emit(c);\n    }\n  }\n\n  activateWith(activatedRoute: ActivatedRoute, environmentInjector: EnvironmentInjector | null): void {\n    if (this.isActivated) {\n      throw new Error('Cannot activate an already activated outlet');\n    }\n    this._activatedRoute = activatedRoute;\n\n    let cmpRef: any;\n    let enteringView = this.stackCtrl.getExistingView(activatedRoute);\n    if (enteringView) {\n      cmpRef = this.activated = enteringView.ref;\n      const saved = enteringView.savedData;\n      if (saved) {\n        // self-restore\n        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n        const context = this.getContext()!;\n        context.children['contexts'] = saved;\n      }\n      // Updated activated route proxy for this component\n      this.updateActivatedRouteProxy(cmpRef.instance, activatedRoute);\n    } else {\n      const snapshot = (activatedRoute as any)._futureSnapshot;","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/ionic-team/ionic-framework/blob/625f9c38ad8c5db8a6c12df5c1622a36da90f9e3/packages/angular/common/src/directives/navigation/router-outlet.ts#L225-L261","documentation":"Thrown by IonRouterOutlet.activateWith() when isActivated is already true. Angular's contract is that an outlet must be deactivated before it is reactivated; activateWith enforces this and fails fast on double-activation. This guards against corrupted navigation state where a new route is activated on top of an existing one without deactivation.","triggerScenarios":"activateWith is called twice without an intervening deactivate(). This can happen with custom routers, mismatched Angular version internals, navigation triggered during an in-flight activation, or a guard/redirect that activates a second route while the first is still active.","commonSituations":"Angular version incompatibility (Ionic Angular vs @angular/router mismatch); redirect/guard logic that triggers concurrent navigations; manually calling router navigation inside a resolver; bugs from mixing NavController and Angular router.navigate in quick succession during transitions.","solutions":["Ensure versions of @ionic/angular and @angular/router are aligned per Ionic's compatibility matrix.","Avoid triggering a second navigation while a page transition/activation is in flight (debounce or queue navigations).","Check outlet.isActivated and let the standard router flow deactivate before reactivating; do not call activateWith directly.","Simplify redirect/guard logic so it does not stack activations on the same outlet."],"exampleFix":"// before\nrouter.navigate(['/a']);\nrouter.navigate(['/b']); // concurrent -> double activation possible\n\n// after\nawait router.navigate(['/a']);\n// transition complete, then\nawait router.navigate(['/b']);","handlingStrategy":"validation","validationCode":"// Don't stack activations: let each navigation settle before the next.\nawait router.navigate(['/a']);\nawait router.navigate(['/b']);\n// Also assert version compatibility at install time (peer deps).","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep @ionic/angular, @ionic/core, and @angular/router versions aligned.","Avoid concurrent/in-flight navigations on the same outlet.","Don't trigger navigation inside resolvers/guards that re-activates the same outlet."],"tags":["angular","router","router-outlet","navigation","version-compat","runtime"],"backgroundTag":null,"analyzedSha":"625f9c38ad8c5db8a6c12df5c1622a36da90f9e3","analyzedAt":"2026-08-12T16:00:25.413Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}