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
LuxonDateAdapter.createDate validates the month argument before constructing a Luxon DateTime. Luxon itself uses 1-indexed months, and the adapter converts from the Material 0-indexed convention internally, so a month outside 0–11 is invalid input. The adapter throws this descriptive error rather than letting Luxon produce an invalid or rolled-over date.
Source
Thrown at src/material-luxon-adapter/adapter/luxon-date-adapter.ts:147
return this._firstDayOfWeek ?? LuxonInfo.getStartOfWeek({locale: this.locale});
}
getNumDaysInMonth(date: LuxonDateTime): number {
return date.daysInMonth!;
}
clone(date: LuxonDateTime): LuxonDateTime {
return LuxonDateTime.fromObject(date.toObject(), {
...this._getOptions(),
zone: date.zone,
});
}
createDate(year: number, month: number, date: number): LuxonDateTime {
const options = this._getOptions();
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.`);
}
// Luxon uses 1-indexed months so we need to add one to the month.
const result = this._useUTC
? LuxonDateTime.utc(year, month + 1, date, options)
: LuxonDateTime.local(year, month + 1, date, options);
if (!this.isValid(result)) {
throw Error(`Invalid date "${date}". Reason: "${result.invalidReason}".`);
}
return result;
}
View on GitHub (pinned to 0411926e7d)
Solutions
- Convert 1-indexed months to 0-indexed before calling: `createDate(y, humanMonth - 1, d)`.
- Clamp or validate the month: `if (month >= 0 && month <= 11) adapter.createDate(y, month, d)`.
- If building from user input, parse via `adapter.parse(value, format)` instead of manual index math.
- Check for off-by-one arithmetic where month is incremented twice.
Example fix
// before const d = adapter.createDate(2024, 12, 15); // throws: 12 out of range // after const d = adapter.createDate(2024, 11, 15); // December, 0-indexed // or from a 1-indexed source: const d = adapter.createDate(2024, humanMonth - 1, 15);
Defensive patterns
Strategy: validation
Validate before calling
function safeCreateDate(adapter: DateAdapter<LuxonDateTime>, y: number, m: number, d: number) {
if (!Number.isInteger(m) || m < 0 || m > 11) {
throw new Error(`month must be 0-11, got ${m}`);
}
return adapter.createDate(y, m, d);
} Type guard
function isValidMonthIndex(m: unknown): m is number {
return typeof m === 'number' && Number.isInteger(m) && m >= 0 && m <= 11;
} Try / catch
try {
return adapter.createDate(y, m, d);
} catch (e) {
if (String(e.message).startsWith('Invalid month index')) return null;
throw e;
} Prevention
- Remember Material adapters use 0-indexed months; subtract 1 from human/Luxon months.
- Add unit tests around month conversion boundaries (0, 11, 12).
- Never pass raw backend months without conversion.
- Watch for arithmetic like `month + 1` applied twice.
When it happens
Trigger: Calling `adapter.createDate(year, month, day)` with month < 0 or month > 11 — e.g. passing a 1-indexed month (1–12) straight from user input or from a legacy 1-indexed API.
Common situations: Mixing 0-indexed (Material/JS Date) and 1-indexed (Luxon, human) month conventions; computing months via arithmetic that overflows (month + 1 == 12); deserializing dates from a backend that sends 1-based months.
Related errors
- Invalid date "${date}". Date has to be greater than 0.
- Formats array must not be empty.
- Invalid minutes "${minutes}". Minutes value must be between
- Formats array must not be empty.
- Invalid date "${date}". Reason: "${result.invalidReason}".
AI-assisted analysis of angular/components@0411926e7d (2026-08-31).
Data as JSON: /api/errors/9a2a5338e85e43d9.
Report an issue: GitHub.