{"record":{"id":"486555e5d4e2f26e","repo":"angular/components","slug":"invalid-date-date-for-month-with-index-mon-486555","errorCode":null,"errorMessage":"Invalid date \"${date}\" for month with index \"${month}\".","messagePattern":"Invalid date \"(.+?)\" for month with index \"(.+?)\"\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/material/core/datetime/native-date-adapter.ts","lineNumber":144,"sourceCode":"  }\n\n  createDate(year: number, month: number, date: number): Date {\n    if (typeof ngDevMode === 'undefined' || ngDevMode) {\n      // Check for invalid month and date (except upper bound on date which we have to check after\n      // creating the Date).\n      if (month < 0 || month > 11) {\n        throw Error(`Invalid month index \"${month}\". Month index has to be between 0 and 11.`);\n      }\n\n      if (date < 1) {\n        throw Error(`Invalid date \"${date}\". Date has to be greater than 0.`);\n      }\n    }\n\n    let result = this._createDateWithOverflow(year, month, date);\n    // Check that the date wasn't above the upper bound for the month, causing the month to overflow\n    if (result.getMonth() != month && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n      throw Error(`Invalid date \"${date}\" for month with index \"${month}\".`);\n    }\n\n    return result;\n  }\n\n  today(): Date {\n    return new Date();\n  }\n\n  parse(value: any, parseFormat?: any): Date | null {\n    // We have no way using the native JS Date to set the parse format or locale, so we ignore these\n    // parameters.\n    if (typeof value == 'number') {\n      return new Date(value);\n    }\n    return value ? new Date(Date.parse(value)) : null;\n  }\n","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/angular/components/blob/0411926e7d8ae06b32236ec1048a888cfad5abf2/src/material/core/datetime/native-date-adapter.ts#L126-L162","documentation":"After building the Date via _createDateWithOverflow, createDate checks whether the resulting .getMonth() still equals the requested month. If not, the day overflowed past the end of the month (e.g. Feb 30 rolls to March 2) and the adapter throws in dev mode to surface invalid date components.","triggerScenarios":"Calling createDate(year, month, day) where day exceeds the month's length — Feb 30, Apr 31, or days derived from user input/leap-year-naive logic.","commonSituations":"Hardcoded end-of-month day 31 for all months; leap-year bugs (Feb 29 in non-leap years); constructing dates from separate year/month/day form fields without validating against daysInMonth.","solutions":["Clamp day to adapter.getNumDaysInMonth(year, month) before creating.","Validate user-supplied year/month/day triplets against the calendar.","Handle Feb 29 explicitly for non-leap years in form logic."],"exampleFix":"// before\nconst d = adapter.createDate(2026, 1, 29); // Feb 29, 2026 not a leap year\n// after\nconst maxDay = adapter.getNumDaysInMonth(2026, 1); // 28\nconst d = adapter.createDate(2026, 1, Math.min(29, maxDay));","handlingStrategy":"validation","validationCode":"const maxDay = adapter.getNumDaysInMonth(year, month);\nif (date > maxDay) {\n  throw new RangeError(`${year}-${month}-${date} overflows month (max ${maxDay})`);\n}\nconst d = adapter.createDate(year, month, date);","typeGuard":"function dayFitsInMonth(y: number, m: number, d: number): boolean {\n  return Number.isInteger(d) && d >= 1 && d <= 31 && d <= new Date(y, m + 1, 0).getDate();\n}","tryCatchPattern":"try {\n  d = adapter.createDate(year, month, date);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('for month with index')) {\n    const max = adapter.getNumDaysInMonth(year, month);\n    d = adapter.createDate(year, month, Math.min(date, max));\n  } else { throw e; }\n}","preventionTips":["Clamp day against getNumDaysInMonth before creating dates.","Handle Feb 29 leap-year logic in date form validation.","Use the adapter's calendar math instead of new Date(y, m, d) directly."],"tags":["angular-material","date-adapter","date-overflow","leap-year"],"backgroundTag":"invalid-date-for-month","analyzedSha":"0411926e7d8ae06b32236ec1048a888cfad5abf2","analyzedAt":"2026-08-31T11:58:23.400Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}