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
- Attach dialog content only once per DialogRef; check container state before attaching (e.g. track whether you already attached).
- Reuse the already-attached content instead of attaching again: read from dialogRef.componentInstance or the container's attached content.
- If you need new content, close the dialog and call Dialog.open again to get a fresh DialogRef/DialogContainer.
- 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
- Track attach state per DialogRef in a flag or Set<DialogRef>.
- Only attach content in one place in your wrapper (e.g. the constructor of the dialog component).
- Reuse dialogRef.componentInstance instead of attaching new content.
- Close and reopen a fresh dialog when content must change.
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
- Dialog with id "${config.id}" exists already. The dialog id
- Host already has a portal attached
- This PortalOutlet has already been disposed
- Attempting to detach a portal that is not attached to a host
- ListKeyManager constructed with a signal must receive an inj
AI-assisted analysis of angular/components@0411926e7d (2026-08-31).
Data as JSON: /api/errors/c2c9fb2832e81025.
Report an issue: GitHub.