angular/components · error · Error
A MatDatepicker can only be associated with a single actions
Error message
A MatDatepicker can only be associated with a single actions row.
What it means
registerActions() enforces that a datepicker has at most one mat-datepicker-actions row. If registerActions is called while an actions portal is already assigned, Material throws this dev-mode error.
Source
Thrown at src/material/datepicker/datepicker-base.ts:626
* @returns Selection model that the input should hook itself up to.
*/
registerInput(input: C): MatDateSelectionModel<S, D> {
if (this.datepickerInput && (typeof ngDevMode === 'undefined' || ngDevMode)) {
throw Error('A MatDatepicker can only be associated with a single input.');
}
this._inputStateChanges.unsubscribe();
this.datepickerInput = input;
this._inputStateChanges = input.stateChanges.subscribe(() => this.stateChanges.next(undefined));
return this._model;
}
/**
* Registers a portal containing action buttons with the datepicker.
* @param portal Portal to be registered.
*/
registerActions(portal: TemplatePortal): void {
if (this._actionsPortal && (typeof ngDevMode === 'undefined' || ngDevMode)) {
throw Error('A MatDatepicker can only be associated with a single actions row.');
}
this._actionsPortal = portal;
this._componentRef?.instance._assignActions(portal, true);
}
/**
* Removes a portal containing action buttons from the datepicker.
* @param portal Portal to be removed.
*/
removeActions(portal: TemplatePortal): void {
if (portal === this._actionsPortal) {
this._actionsPortal = null;
this._componentRef?.instance._assignActions(null, true);
}
}
/** Open the calendar. */
open(): void {View on GitHub (pinned to 0411926e7d)
Solutions
- Keep exactly one <mat-datepicker-actions> inside the datepicker.
- Before registering a new portal programmatically, clear or replace the existing _actionsPortal.
- Restructure shared datepicker templates so actions are defined once.
Example fix
// before <mat-datepicker #picker> <mat-datepicker-actions><button mat-button>OK</button></mat-datepicker-actions> <mat-datepicker-actions><button mat-button>CANCEL</button></mat-datepicker-actions> </mat-datepicker> // after <mat-datepicker #picker> <mat-datepicker-actions><button mat-button>OK</button></mat-datepicker-actions> </mat-datepicker>
Defensive patterns
Strategy: validation
Validate before calling
// Assert exactly one actions row per datepicker in shared templates
function countActions(dp: HTMLElement): number {
return dp.querySelectorAll('mat-datepicker-actions').length;
} Prevention
- Define mat-datepicker-actions once per datepicker instance.
- When registering portals programmatically, track current portal state before re-registering.
- Extract the actions block into a shared component used once per picker.
When it happens
Trigger: Declaring <mat-datepicker-actions> twice within one <mat-datepicker>; dynamically attaching an actions portal via registerActions() while one is already registered without unregistering.
Common situations: Duplicating the actions block during copy-paste; programmatic code calling registerActions on each open/creation cycle without clearing the previous portal.
Related errors
- MatDatepicker: No provider found for DateAdapter. You must a
- MatDatepicker: No provider found for MAT_DATE_FORMATS. You m
- MatDatepicker: No provider found for DateAdapter. You must a
- mat-date-range-input must contain a matStartDate input
- mat-date-range-input must contain a matEndDate input
AI-assisted analysis of angular/components@0411926e7d (2026-08-31).
Data as JSON: /api/errors/68804e93919f5972.
Report an issue: GitHub.