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

  1. Create a fresh strategy per overlay: call overlay.position().flexibleConnectedTo(origin) each time you create an overlay.
  2. If the same overlay should be reused, keep the original OverlayRef and call updatePosition() instead of attaching again.
  3. Dispose the old overlay (overlayRef.dispose()) before attaching the strategy to a new one — but prefer building a new strategy.
  4. 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

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


AI-assisted analysis of angular/components@0411926e7d (2026-08-31). Data as JSON: /api/errors/6853c65b4a5eb8bd. Report an issue: GitHub.