angular/components · error · Error
This position strategy is already attached to an overlay
Error message
This position strategy is already attached to an overlay
What it means
A FlexibleConnectedPositionStrategy can only be attached to a single OverlayRef. attach() throws if the strategy already has an _overlayRef and a different overlay is being attached. The strategy stores its overlay ref to compute positions; sharing it across overlays would corrupt that state.
Source
Thrown at src/cdk/overlay/position/flexible-connected-position-strategy.ts:195
constructor(
connectedTo: FlexibleConnectedPositionStrategyOrigin,
private _viewportRuler: ViewportRuler,
private _document: Document,
private _platform: Platform,
private _overlayContainer: OverlayContainer,
) {
this.setOrigin(connectedTo);
}
/** Attaches this position strategy to an overlay. */
attach(overlayRef: OverlayRef): void {
if (
this._overlayRef &&
overlayRef !== this._overlayRef &&
(typeof ngDevMode === 'undefined' || ngDevMode)
) {
throw Error('This position strategy is already attached to an overlay');
}
this._validatePositions();
overlayRef.hostElement.classList.add(boundingBoxClass);
this._overlayRef = overlayRef;
this._boundingBox = overlayRef.hostElement;
this._pane = overlayRef.overlayElement;
this._isDisposed = false;
this._isInitialRender = true;
this._lastPosition = null;
this._resizeSubscription.unsubscribe();
this._resizeSubscription = this._viewportRuler.change().subscribe(() => {
// When the window is resized, we want to trigger the next reposition as if it
// was an initial render, in order for the strategy to pick a new optimal position,
// otherwise position locking will cause it to stay at the old one.
this._isInitialRender = true;View on GitHub (pinned to 0411926e7d)
Solutions
- Create a fresh strategy per overlay: call overlay.position().flexibleConnectedTo(origin) each time you create an overlay.
- If the same overlay should be reused, keep the original OverlayRef and call updatePosition() instead of attaching again.
- Dispose the old overlay (overlayRef.dispose()) before attaching the strategy to a new one — but prefer building a new strategy.
- Move strategy construction inside your open() method so it is never shared across overlay instances.
Example fix
// before
this.strategy = this.overlay.position().flexibleConnectedTo(origin);
this.overlay.create({ positionStrategy: this.strategy }); // first
this.overlay.create({ positionStrategy: this.strategy }); // throws
// after
const strategy = this.overlay.position().flexibleConnectedTo(origin);
this.overlayRef = this.overlay.create({ positionStrategy: strategy }); Defensive patterns
Strategy: fallback
Validate before calling
if (!strategyRef || strategyRef.hasAttached()) {
strategyRef = overlay.position().flexibleConnectedTo(origin);
}
const ref = overlay.create({ positionStrategy: strategyRef }); Try / catch
try {
overlayRef = overlay.create({ positionStrategy: strategy });
} catch (e) {
if ((e as Error).message.includes('already attached to an overlay')) {
overlayRef = overlay.create({ positionStrategy: overlay.position().flexibleConnectedTo(origin) });
} else { throw e; }
} Prevention
- Create a new position strategy for every overlay.create call.
- Never cache FlexibleConnectedPositionStrategy instances in services for reuse.
- Call updatePosition() on the existing overlay instead of re-attaching.
- Dispose overlays promptly so strategies are not reused after detach.
When it happens
Trigger: Reusing one position strategy object (created via overlay.position().flexibleConnectedTo(origin)) for a second overlay.create() call; caching a strategy in a service and attaching it to a new overlay after the first.
Common situations: Opening multiple tooltips/popovers that share a prebuilt strategy; recreating an overlay without rebuilding the strategy; retry logic that re-calls overlay.create with the same strategy instance.
Related errors
- ConnectedPosition: Invalid ${property} "${value}". Expected
- ConnectedPosition: Invalid ${property} "${value}". Expected
- FlexibleConnectedPositionStrategy: At least one position is
- Scroll strategy has already been attached.
- Scroll strategy has already been attached.
AI-assisted analysis of angular/components@0411926e7d (2026-08-31).
Data as JSON: /api/errors/6853c65b4a5eb8bd.
Report an issue: GitHub.