angular/components · error · Error
LuxonDateAdapter: Cannot format invalid date.
Error message
LuxonDateAdapter: Cannot format invalid date.
What it means
LuxonDateAdapter.format refuses to format an invalid LuxonDateTime, because Luxon would return the string 'Invalid DateTime' and silently corrupt the UI. The adapter throws a descriptive error instead, enforcing that only valid dates reach the display layer.
Source
Thrown at src/material-luxon-adapter/adapter/luxon-date-adapter.ts:210
return fromFormat;
}
}
return this.invalid();
} else if (typeof value === 'number') {
return LuxonDateTime.fromMillis(value, options);
} else if (value instanceof Date) {
return LuxonDateTime.fromJSDate(value, options);
} else if (value instanceof LuxonDateTime) {
return LuxonDateTime.fromMillis(value.toMillis(), options);
}
return null;
}
format(date: LuxonDateTime, displayFormat: string): string {
if (!this.isValid(date)) {
throw Error('LuxonDateAdapter: Cannot format invalid date.');
}
if (this._useUTC) {
return date.setLocale(this.locale).setZone('utc').toFormat(displayFormat);
} else {
return date.setLocale(this.locale).toFormat(displayFormat);
}
}
addCalendarYears(date: LuxonDateTime, years: number): LuxonDateTime {
return date.reconfigure(this._getOptions()).plus({years});
}
addCalendarMonths(date: LuxonDateTime, months: number): LuxonDateTime {
return date.reconfigure(this._getOptions()).plus({months});
}
addCalendarDays(date: LuxonDateTime, days: number): LuxonDateTime {
return date.reconfigure(this._getOptions()).plus({days});View on GitHub (pinned to 0411926e7d)
Solutions
- Check `adapter.isValid(date)` before formatting and render a placeholder for invalid values.
- If the date came from JSON persistence, rehydrate with `LuxonDateTime.fromISO`/`fromMillis`, not JSON.parse.
- Handle parse() returning null for unparseable input before using the result.
- Catch this error at the display boundary and fall back to a fallback string like '—' or 'Invalid date'.
Example fix
// before const text = adapter.parse(userInput, 'yyyy-MM-dd'); display = adapter.format(text, 'dd/MM/yyyy'); // may throw // after display = text && adapter.isValid(text) ? adapter.format(text, 'dd/MM/yyyy') : '—';
Defensive patterns
Strategy: type-guard
Validate before calling
function safeFormat(adapter: DateAdapter<LuxonDateTime>, date: LuxonDateTime | null, fmt: string): string {
return date && adapter.isValid(date) ? adapter.format(date, fmt) : '—';
} Type guard
function isValidLuxonDate(adapter: DateAdapter<LuxonDateTime>, d: LuxonDateTime | null | undefined): d is LuxonDateTime {
return d != null && adapter.isValid(d);
} Try / catch
try {
return adapter.format(date, displayFormat);
} catch (e) {
if (String(e.message).includes('Cannot format invalid date')) return 'Invalid date';
throw e;
} Prevention
- Always check adapter.isValid() before formatting or binding dates to the UI.
- Rehydrate persisted dates with LuxonDateTime.fromISO/fromMillis, never JSON.parse.
- Treat a null return from parse() as 'no date', not an invalid date.
- Centralize formatting in one helper that performs the validity check.
When it happens
Trigger: Calling `adapter.format(date, displayFormat)` with a date that came from `LuxonDateTime.invalid(...)`, from a failed `fromFormat`/`fromISO` call, or from `adapter.createDate` logic bypassed manually; also when a date stored/retrieved from storage deserialized to an invalid DateTime.
Common situations: Displaying dates parsed from malformed user input without checking isValid; reviving persisted dates with JSON.parse (produces plain objects/invalid DateTimes); passing results of failed parse() calls straight into the datepicker's display pipeline.
Related errors
- Invalid date "${date}". Reason: "${result.invalidReason}".
- NativeDateAdapter: Cannot format invalid date.
- Invalid month index "${month}". Month index has to be betwee
- Invalid date "${date}". Date has to be greater than 0.
- Formats array must not be empty.
AI-assisted analysis of angular/components@0411926e7d (2026-08-31).
Data as JSON: /api/errors/f49790f9dedc489c.
Report an issue: GitHub.