angular/components · error
This PortalOutlet has already been disposed
Error message
This PortalOutlet has already been disposed
What it means
`throwPortalOutletAlreadyDisposedError` fires when `attach` is called on an outlet whose `dispose()` has already run. A disposed outlet has torn down its resources and can never host a portal again; a new outlet instance is required.
Source
Thrown at src/cdk/portal/portal-errors.ts:30
*/
export function throwNullPortalError() {
throw Error('Must provide a portal to attach');
}
/**
* Throws an exception when attempting to attach a portal to a host that is already attached.
* @docs-private
*/
export function throwPortalAlreadyAttachedError() {
throw Error('Host already has a portal attached');
}
/**
* Throws an exception when attempting to attach a portal to an already-disposed host.
* @docs-private
*/
export function throwPortalOutletAlreadyDisposedError() {
throw Error('This PortalOutlet has already been disposed');
}
/**
* Throws an exception when attempting to attach an unknown portal type.
* @docs-private
*/
export function throwUnknownPortalTypeError() {
throw Error(
'Attempting to attach an unknown Portal type. BasePortalOutlet accepts either ' +
'a ComponentPortal or a TemplatePortal.',
);
}
/**
* Throws an exception when attempting to attach a portal to a null host.
* @docs-private
*/
export function throwNullPortalOutletError() {View on GitHub (pinned to 0411926e7d)
Solutions
- Create a new outlet instance after dispose instead of reusing it
- Guard with a disposed flag/`isDisposed` check before attach
- Cancel pending async work (takeUntilDestroyed, unsubscribe) so attach never runs post-dispose
- Move outlet creation/dispose into the same component lifecycle as the attach logic
Example fix
// before this.outlet.dispose(); this.outlet.attach(portal); // throws // after this.outlet.dispose(); this.outlet = new DomPortalOutlet(hostEl, injector, appRef, document); this.outlet.attach(portal);
Defensive patterns
Strategy: try-catch
Validate before calling
if (!disposed) outlet.attach(portal);
Try / catch
try { outlet.attach(portal); } catch (e) { if (String(e.message).includes('already been disposed')) { outlet = createOutlet(); outlet.attach(portal); } else { throw e; } } Prevention
- Null cached outlets on dispose
- Cancel async attaches on teardown
- Rebuild outlets after dispose
When it happens
Trigger: Calling `attach` on a DomPortalOutlet after `outlet.dispose()`; using a cached/stored outlet reference after its host was destroyed; attaching a portal in a component whose outlet was disposed during teardown (e.g. after NavigationEnd cleanup).
Common situations: Long-lived services caching outlets for destroyed overlays; async callbacks (HTTP, timers) resolving after dispose; HMR or route changes disposing outlets while pending attaches are in flight.
Related errors
- Host already has a portal attached
- Attempting to detach a portal that is not attached to a host
- Attempting to attach dialog content after content is already
- Cannot attach component portal to outlet without an Applicat
- DOM portal content must be attached to a parent node.
AI-assisted analysis of angular/components@0411926e7d (2026-08-31).
Data as JSON: /api/errors/047e050fb0039a14.
Report an issue: GitHub.