ionic-team/ionic-framework · critical · Error
Cannot activate an already activated outlet
Error message
Cannot activate an already activated outlet
What it means
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.
Source
Thrown at packages/angular/common/src/directives/navigation/router-outlet.ts:243
this.activatedView.savedExtras = {};
if (context.route) {
const contextSnapshot = context.route.snapshot;
this.activatedView.savedExtras.queryParams = contextSnapshot.queryParams;
(this.activatedView.savedExtras.fragment as string | null) = contextSnapshot.fragment;
}
}
const c = this.component;
this.activatedView = null;
this.activated = null;
this._activatedRoute = null;
this.deactivateEvents.emit(c);
}
}
activateWith(activatedRoute: ActivatedRoute, environmentInjector: EnvironmentInjector | null): void {
if (this.isActivated) {
throw new Error('Cannot activate an already activated outlet');
}
this._activatedRoute = activatedRoute;
let cmpRef: any;
let enteringView = this.stackCtrl.getExistingView(activatedRoute);
if (enteringView) {
cmpRef = this.activated = enteringView.ref;
const saved = enteringView.savedData;
if (saved) {
// self-restore
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const context = this.getContext()!;
context.children['contexts'] = saved;
}
// Updated activated route proxy for this component
this.updateActivatedRouteProxy(cmpRef.instance, activatedRoute);
} else {
const snapshot = (activatedRoute as any)._futureSnapshot;View on GitHub (pinned to 625f9c38ad)
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.
Example fix
// before router.navigate(['/a']); router.navigate(['/b']); // concurrent -> double activation possible // after await router.navigate(['/a']); // transition complete, then await router.navigate(['/b']);
Defensive patterns
Strategy: validation
Validate before calling
// Don't stack activations: let each navigation settle before the next. await router.navigate(['/a']); await router.navigate(['/b']); // Also assert version compatibility at install time (peer deps).
Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Could not find activated route proxy for view
- Outlet is not activated
- incompatible reuse strategy
- Invalid hour cycle "${hourCycle}"
- Invalid hour cycle "${hourCycle}"
AI-assisted analysis of ionic-team/ionic-framework@625f9c38ad (2026-08-12).
Data as JSON: /api/errors/3afdf01052fd8655.
Report an issue: GitHub.