angular/components · error
Invalid month index "${month}". Month index has to be betwee
Error message
Invalid month index "${month}". Month index has to be between 0 and 11. What it means
DateFnsAdapter.createDate validates the month argument and throws when it falls outside 0–11 (date-fns/Material use zero-based months: 0=January, 11=December). The check runs in dev mode. This prevents silently rolling the date into the next year/month via Date overflow.
Source
Thrown at src/material-date-fns-adapter/adapter/date-fns-adapter.ts:136
getFirstDayOfWeek(): number {
return this.locale.options?.weekStartsOn ?? 0;
}
getNumDaysInMonth(date: Date): number {
return getDaysInMonth(date);
}
clone(date: Date): Date {
return new Date(date.getTime());
}
createDate(year: number, month: number, date: number): Date {
if (typeof ngDevMode === 'undefined' || ngDevMode) {
// Check for invalid month and date (except upper bound on date which we have to check after
// creating the Date).
if (month < 0 || month > 11) {
throw Error(`Invalid month index "${month}". Month index has to be between 0 and 11.`);
}
if (date < 1) {
throw Error(`Invalid date "${date}". Date has to be greater than 0.`);
}
}
// Passing the year to the constructor causes year numbers <100 to be converted to 19xx.
// To work around this we use `setFullYear` and `setHours` instead.
const result = new Date();
result.setFullYear(year, month, date);
result.setHours(0, 0, 0, 0);
// Check that the date wasn't above the upper bound for the month, causing the month to overflow
if (result.getMonth() != month && (typeof ngDevMode === 'undefined' || ngDevMode)) {
throw Error(`Invalid date "${date}" for month with index "${month}".`);
}
View on GitHub (pinned to 0411926e7d)
Solutions
- Subtract 1 from one-based month values before calling createDate.
- Wrap month arithmetic with modulo: (month + 11) % 12 when decrementing.
- Use date-fns helpers like setMonth/addMonths instead of raw indices.
- Validate user-supplied month input against 1–12 before conversion.
Example fix
// before this.adapter.createDate(2024, 12, 25); // intended December, throws // after this.adapter.createDate(2024, 11, 25); // zero-based: 11 = December
Defensive patterns
Strategy: validation
Validate before calling
if (!Number.isInteger(month) || month < 0 || month > 11) {
throw new RangeError(`month must be 0-11, got ${month}`);
}
const d = adapter.createDate(year, month, date); Type guard
function isValidMonthIndex(m: unknown): m is number {
return typeof m === 'number' && Number.isInteger(m) && m >= 0 && m <= 11;
} Try / catch
try {
return this.adapter.createDate(year, month, day);
} catch (e) {
if ((e as Error).message.startsWith('Invalid month index')) {
return this.adapter.createDate(year, Math.min(Math.max(month, 0), 11), day);
}
throw e;
} Prevention
- Always convert one-based months (form/UI input) with month - 1
- Use (m + 11) % 12 wrapping for previous-month arithmetic
- Prefer adapter methods (addCalendarMonths, setMonth equivalents) over raw indices
- Document zero-based convention wherever createDate is called
When it happens
Trigger: Calling adapter.createDate(year, month, date) with month < 0 or month > 11 — e.g. passing a human month number like 12 for December instead of 11, or -1 when computing previous month by naive subtraction.
Common situations: Converting from one-based user input (month pickers, forms) without subtracting 1; month arithmetic like currentMonth - 1 going below 0 without wrapping; mixing DateAdapter implementations with different conventions.
Related errors
- Invalid date "${date}". Date has to be greater than 0.
- Invalid hours "${hours}". Hours value must be between 0 and
- Invalid minutes "${minutes}". Minutes value must be between
- Invalid seconds "${seconds}". Seconds value must be between
- Invalid date "${date}" for month with index "${month}".
AI-assisted analysis of angular/components@0411926e7d (2026-08-31).
Data as JSON: /api/errors/bae2bdfb9c38685a.
Report an issue: GitHub.