angular/components · error · Error

Attempting to attach dialog content after content is already

Error message

Attempting to attach dialog content after content is already attached

What it means

The CDK Dialog's DialogContainer allows user content (a component portal or template portal) to be attached exactly once. throwDialogContentAlreadyAttachedError fires when attachComponentPortal, attachTemplatePortal, or attachDomPortal is called after content is already attached to the container. This guards against rendering two content nodes into one dialog overlay.

Source

Thrown at src/cdk/dialog/dialog-container.ts:46

  Component,
  ComponentRef,
  ElementRef,
  EmbeddedViewRef,
  Injector,
  NgZone,
  OnDestroy,
  Renderer2,
  ViewChild,
  ViewEncapsulation,
  afterNextRender,
  inject,
  DOCUMENT,
} from '@angular/core';
import {DialogConfig, DialogContainer} from './dialog-config';
import {Observable, Subject} from 'rxjs';

export function throwDialogContentAlreadyAttachedError() {
  throw Error('Attempting to attach dialog content after content is already attached');
}

/**
 * Internal component that wraps user-provided dialog content.
 * @docs-private
 */
@Component({
  selector: 'cdk-dialog-container',
  templateUrl: './dialog-container.html',
  styleUrl: 'dialog-container.css',
  encapsulation: ViewEncapsulation.None,
  // Using OnPush for dialogs caused some G3 sync issues. Disabled until we can track them down.
  // tslint:disable-next-line:validate-decorators
  changeDetection: ChangeDetectionStrategy.Eager,
  imports: [CdkPortalOutlet],
  host: {
    'class': 'cdk-dialog-container',
    'tabindex': '-1',

View on GitHub (pinned to 0411926e7d)

Solutions

  1. Attach dialog content only once per DialogRef; check container state before attaching (e.g. track whether you already attached).
  2. Reuse the already-attached content instead of attaching again: read from dialogRef.componentInstance or the container's attached content.
  3. If you need new content, close the dialog and call Dialog.open again to get a fresh DialogRef/DialogContainer.
  4. Guard multiple attach calls with a flag or an `if (!container.hasAttached())`-style check.

Example fix

// before
this.dialog.open(MyDialog).componentInstance;
container.attachComponentPortal(new ComponentPortal(OtherComp)); // throws if content attached
// after
if (!this.attached) {
  container.attachComponentPortal(new ComponentPortal(OtherComp));
  this.attached = true;
}
Defensive patterns

Strategy: validation

Validate before calling

if (container.hasAttached()) {
  throw new Error('Dialog content already attached; skipping attach.');
}
container.attachComponentPortal(portal);

Type guard

function canAttach(container: DialogContainer): boolean {
  return !container.hasAttached();
}

Try / catch

try {
  container.attachComponentPortal(portal);
} catch (e) {
  if ((e as Error).message.includes('already attached')) {
    // content already present; reuse existing dialog
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling dialogRef/DialogContainer attach methods a second time on the same dialog, e.g. calling dialogRef.componentInstance re-attach logic, programmatically calling container.attachComponentPortal twice, or re-opening logic that attaches content to an already-populated DialogRef.

Common situations: Custom dialog wrappers that retry attach on error without checking if content is attached; ngDoCheck-based logic that attaches content repeatedly; reusing a single DialogRef for multiple opens.

Related errors


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