angular/components · error · 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

MomentDateAdapter.createDate builds a Moment from year/month/day components. Moment silently produces invalid dates for out-of-bounds components, so the adapter explicitly checks month (0-11, JavaScript-style zero-based index) and throws this error to give a clearer message than an 'Invalid Date' downstream. The check runs only in ngDevMode.

Source

Thrown at src/material-moment-adapter/adapter/moment-date-adapter.ts:155

  getFirstDayOfWeek(): number {
    return this._localeData.firstDayOfWeek;
  }

  getNumDaysInMonth(date: Moment): number {
    return this.clone(date).daysInMonth();
  }

  clone(date: Moment): Moment {
    return date.clone().locale(this.locale);
  }

  createDate(year: number, month: number, date: number): Moment {
    // Moment.js will create an invalid date if any of the components are out of bounds, but we
    // explicitly check each case so we can throw more descriptive errors.
    if (typeof ngDevMode === 'undefined' || ngDevMode) {
      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.`);
      }
    }

    const result = this._createMoment({year, month, date}).locale(this.locale);

    // If the result isn't valid, the date must have been out of bounds for this month.
    if (!result.isValid() && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      throw Error(`Invalid date "${date}" for month with index "${month}".`);
    }

    return result;
  }

  today(): Moment {

View on GitHub (pinned to 0411926e7d)

Solutions

  1. Subtract 1 from 1-based month values: createDate(2024, month - 1, day).
  2. Validate month is 0-11 before calling createDate.
  3. Ensure UI pickers/schemas consistently use zero-based months for this adapter.
  4. Check any code that recently switched moment date handling to Angular Material for a base-0/base-1 mismatch.

Example fix

// before
const date = adapter.createDate(2024, 3, 15); // intended March, passed 3 (zero-based = April)
// after
const date = adapter.createDate(2024, 2, 15); // March in zero-based indexing
Defensive patterns

Strategy: validation

Validate before calling

function canCreateMonth(month: number): boolean {
  return Number.isInteger(month) && month >= 0 && month <= 11;
}
const safeMonth = isOneBased(month) ? month - 1 : month;

Type guard

function isZeroBasedMonth(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 (e instanceof Error && e.message.includes('Invalid month index')) {
    return adapter.createDate(y, m - 1, d); // likely 1-based input
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling createDate(year, month, date) with month < 0 or month > 11, most often by passing a 1-based month (January as 1) into the zero-based API, or from setLocale/newDate internal flows with bad data.

Common situations: Migrating from APIs that use 1-based months, storing month values from user pickers that are 1-based, off-by-one in loops building calendars, backend payloads returning 1-12 months.

Related errors


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