angular/components · error · Error
Dialog with id "${config.id}" exists already. The dialog id
Error message
Dialog with id "${config.id}" exists already. The dialog id must be unique. What it means
Dialog.open(config) rejects a custom config.id that is already in use by an open dialog. Because duplicate ids would break getDialogById and afterClosed lookups, the CDK throws when `config.id` matches an existing dialog's id. This check only runs in development (ngDevMode) but the constraint holds in production too.
Source
Thrown at src/cdk/dialog/dialog.ts:132
): DialogRef<R, C>;
open<R = unknown, D = unknown, C = unknown>(
componentOrTemplateRef: ComponentType<C> | TemplateRef<C>,
config?: DialogConfig<D, DialogRef<R, C>>,
): DialogRef<R, C> {
const defaults = (this._defaultOptions || new DialogConfig()) as DialogConfig<
D,
DialogRef<R, C>
>;
config = {...defaults, ...config};
config.id = config.id || this._idGenerator.getId('cdk-dialog-');
if (
config.id &&
this.getDialogById(config.id) &&
(typeof ngDevMode === 'undefined' || ngDevMode)
) {
throw Error(`Dialog with id "${config.id}" exists already. The dialog id must be unique.`);
}
const overlayConfig = this._getOverlayConfig(config);
const overlayRef = createOverlayRef(this._injector, overlayConfig);
const dialogRef = new DialogRef(overlayRef, config);
const dialogContainer = this._attachContainer(overlayRef, dialogRef, config);
(dialogRef as {containerInstance: DialogContainer}).containerInstance = dialogContainer;
// If this is the first dialog that we're opening, hide all the non-overlay content.
if (!this.openDialogs.length) {
// Resolve this ahead of time, because some internal apps
// mock it out and depend on it being synchronous.
const overlayContainer = this._overlayContainer.getContainerElement();
if (dialogContainer._focusTrapped) {
dialogContainer._focusTrapped.pipe(take(1)).subscribe(() => {
this._hideNonDialogContentFromAssistiveTechnology(overlayContainer);View on GitHub (pinned to 0411926e7d)
Solutions
- Close the existing dialog first: find it via `this.dialog.getDialogById('my-id')?.close()` before opening.
- Generate unique ids at runtime, e.g. `id: 'dialog-' + Math.random().toString(36).slice(2)` or a counter/UUID.
- Reuse the existing dialog: if getDialogById returns one, focus/interact with it instead of opening a new one.
- Omit the `id` property if you don't need deterministic lookup — Angular CDK assigns an auto id.
- Track open state in a service so the same id is never passed while open.
Example fix
// before
this.dialog.open(SettingsComponent, { id: 'settings' });
// after
const existing = this.dialog.getDialogById('settings');
if (existing) {
existing.close();
}
this.dialog.open(SettingsComponent, { id: 'settings' }); Defensive patterns
Strategy: validation
Validate before calling
const id = 'settings';
if (dialog.getDialogById(id)) {
dialog.getDialogById(id)!.close(); // or return early
}
dialog.open(SettingsComponent, { id }); Type guard
function isOpen(dialog: Dialog, id: string): boolean {
return !!dialog.getDialogById(id);
} Try / catch
try {
return dialog.open(Comp, { id: 'fixed-id' });
} catch (e) {
if ((e as Error).message.includes('exists already')) {
return dialog.getDialogById('fixed-id')!;
}
throw e;
} Prevention
- Always check getDialogById before opening with a fixed id.
- Prefer auto-generated ids unless lookup is required.
- Use a service holding open dialog state for repeatable UI (rows, tabs).
- Close dialogs in ngOnDestroy to avoid leaks causing future duplicates.
When it happens
Trigger: Calling this.dialog.open(SomeComponent, { id: 'settings' }) while a dialog with id 'settings' is still open; rendering two dialogs with the same hardcoded id, e.g. in a component rendered twice.
Common situations: Same dialog component instantiated in two places (list rows, tabs) each passing a shared static id; forgetting to close a dialog before reopening it with the same id; HMR or router re-entry leaving the old dialog open.
Related errors
- Attempting to attach dialog content after content is already
- ListKeyManager constructed with a signal must receive an inj
- KeyManager items in typeahead mode must implement the `getLa
- CdkDropList could not find an element container matching the
- Invalid DOM structure for drop list. Alternate container ele
AI-assisted analysis of angular/components@0411926e7d (2026-08-31).
Data as JSON: /api/errors/08965d69c167e520.
Report an issue: GitHub.