angular/components · error

Invalid date "${date}" for month with index "${month}".

Error message

Invalid date "${date}" for month with index "${month}".

What it means

After building the Date via setFullYear(year, month, date), DateFnsAdapter checks whether the resulting month still equals the requested month. If the day exceeded the month's length (e.g. Feb 30), JavaScript's Date overflows into the next month, and the adapter throws to catch it (dev mode).

Source

Thrown at src/material-date-fns-adapter/adapter/date-fns-adapter.ts:152

      // 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}".`);
    }

    return result;
  }

  today(): Date {
    return new Date();
  }

  parse(value: unknown, parseFormat: string | string[]): Date | null {
    return this._parse(value, parseFormat);
  }

  format(date: Date, displayFormat: string): string {
    if (!this.isValid(date)) {
      throw Error('DateFnsAdapter: Cannot format invalid date.');
    }

View on GitHub (pinned to 0411926e7d)

Solutions

  1. Validate the day against the actual days in the month before calling createDate (use date-fns getDaysInMonth logic).
  2. Clamp the day: Math.min(day, daysInMonth(year, month)).
  3. For 'end of month' semantics use date-fns endOfMonth instead of day 31.
  4. Fix leap-year handling for February dates.

Example fix

// before
const d = this.adapter.createDate(2024, 1, 30); // Feb 30 -> throws
// after
const day = Math.min(30, 29); // daysInMonth(2024, 1) = 29
const d = this.adapter.createDate(2024, 1, day);
Defensive patterns

Strategy: validation

Validate before calling

const daysInMonth = new Date(year, month + 1, 0).getDate();
if (date < 1 || date > daysInMonth) {
  throw new RangeError(`date ${date} out of range for month ${month} (1-${daysInMonth})`);
}
const d = adapter.createDate(year, month, date);

Type guard

function isValidDateForMonth(y: number, m: number, d: number): boolean {
  return d >= 1 && d <= new Date(y, m + 1, 0).getDate();
}

Try / catch

try {
  return this.adapter.createDate(year, month, day);
} catch (e) {
  if ((e as Error).message.startsWith('Invalid date "') && e.message.includes('for month')) {
    const max = new Date(year, month + 1, 0).getDate();
    return this.adapter.createDate(year, month, Math.min(day, max));
  }
  throw e;
}

Prevention

When it happens

Trigger: createDate(2024, 1, 30) (Feb 30), createDate(year, 3, 31) (Apr 31), or any day number greater than the target month's day count — including February on non-leap years (Feb 29 in 2023).

Common situations: Building dates from separate user-selected year/month/day fields without validating day against the month; hard-coded day values like 31; leap-year bugs with Feb 29.

Related errors


AI-assisted analysis of angular/components@0411926e7d (2026-08-31). Data as JSON: /api/errors/bb4a8fa7c888d6b0. Report an issue: GitHub.