{"record":{"id":"9a2a5338e85e43d9","repo":"angular/components","slug":"invalid-month-index-month-month-index-has-to-9a2a53","errorCode":null,"errorMessage":"Invalid month index \"${month}\". Month index has to be between 0 and 11.","messagePattern":"Invalid month index \"(.+?)\"\\. Month index has to be between 0 and 11\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/material-luxon-adapter/adapter/luxon-date-adapter.ts","lineNumber":147,"sourceCode":"    return this._firstDayOfWeek ?? LuxonInfo.getStartOfWeek({locale: this.locale});\n  }\n\n  getNumDaysInMonth(date: LuxonDateTime): number {\n    return date.daysInMonth!;\n  }\n\n  clone(date: LuxonDateTime): LuxonDateTime {\n    return LuxonDateTime.fromObject(date.toObject(), {\n      ...this._getOptions(),\n      zone: date.zone,\n    });\n  }\n\n  createDate(year: number, month: number, date: number): LuxonDateTime {\n    const options = this._getOptions();\n\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    // Luxon uses 1-indexed months so we need to add one to the month.\n    const result = this._useUTC\n      ? LuxonDateTime.utc(year, month + 1, date, options)\n      : LuxonDateTime.local(year, month + 1, date, options);\n\n    if (!this.isValid(result)) {\n      throw Error(`Invalid date \"${date}\". Reason: \"${result.invalidReason}\".`);\n    }\n\n    return result;\n  }\n","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/angular/components/blob/0411926e7d8ae06b32236ec1048a888cfad5abf2/src/material-luxon-adapter/adapter/luxon-date-adapter.ts#L129-L165","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nconst d = adapter.createDate(2024, 12, 15); // throws: 12 out of range\n\n// after\nconst d = adapter.createDate(2024, 11, 15); // December, 0-indexed\n// or from a 1-indexed source:\nconst d = adapter.createDate(2024, humanMonth - 1, 15);","handlingStrategy":"validation","validationCode":"function safeCreateDate(adapter: DateAdapter<LuxonDateTime>, y: number, m: number, d: number) {\n  if (!Number.isInteger(m) || m < 0 || m > 11) {\n    throw new Error(`month must be 0-11, got ${m}`);\n  }\n  return adapter.createDate(y, m, d);\n}","typeGuard":"function isValidMonthIndex(m: unknown): m is number {\n  return typeof m === 'number' && Number.isInteger(m) && m >= 0 && m <= 11;\n}","tryCatchPattern":"try {\n  return adapter.createDate(y, m, d);\n} catch (e) {\n  if (String(e.message).startsWith('Invalid month index')) return null;\n  throw e;\n}","preventionTips":["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."],"tags":["angular-material","luxon","date-arithmetic","invalid-argument","off-by-one"],"backgroundTag":"invalid-month-index","analyzedSha":"0411926e7d8ae06b32236ec1048a888cfad5abf2","analyzedAt":"2026-08-31T11:58:23.400Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}