TheAlgorithms/JavaScript · error · TypeError

Invalid Month Number.

Error message

Invalid Month Number.

What it means

Thrown by getMonthDays() in Timing-Functions/GetMonthDays.js when monthNumber is not in the 31-day set [1,3,5,7,8,10,12], the 30-day set [4,6,9,11], and is not exactly 2 (February). A TypeError rejecting months like 0, 13, -1, or non-integer values that are not literally 2. The check uses strict includes, so 2.0 (which === 2) is accepted but 2.5 is rejected.

Source

Thrown at Timing-Functions/GetMonthDays.js:20

  function that takes month number and its year and returns the number of days within it
  * @param monthNumber.
  * @param year.
  e.g.: mahfoudh.arous@gmail.com -> true
  e.g.: mahfoudh.arous.com ->false
*/

import { isLeapYear } from '../Maths/LeapYear'

const getMonthDays = (monthNumber, year) => {
  const the31DaysMonths = [1, 3, 5, 7, 8, 10, 12]
  const the30DaysMonths = [4, 6, 9, 11]

  if (
    !the31DaysMonths.includes(monthNumber) &&
    !the30DaysMonths.includes(monthNumber) &&
    monthNumber !== 2
  ) {
    throw new TypeError('Invalid Month Number.')
  }

  if (the31DaysMonths.includes(monthNumber)) {
    return 31
  }

  if (the30DaysMonths.includes(monthNumber)) {
    return 30
  }

  if (isLeapYear(year)) {
    return 29
  }

  return 28
}

export { getMonthDays }

View on GitHub (pinned to 5c39e87a9a)

Solutions

  1. If your source is 0-based (Date.getMonth()), add 1: getMonthDays(date.getMonth() + 1, year).
  2. Ensure the month is an integer in 1..12 before calling: const m = Number(month); if (m >= 1 && m <= 12) getMonthDays(m, year).
  3. Validate with Number.isInteger(monthNumber) && monthNumber >= 1 && monthNumber <= 12.
  4. Check that you are not passing a string month from form data — parseInt(it, 10) first.

Example fix

// before
const days = getMonthDays(jsDate.getMonth(), jsDate.getFullYear()) // 0..11

// after
const days = getMonthDays(jsDate.getMonth() + 1, jsDate.getFullYear())
Defensive patterns

Strategy: validation

Validate before calling

function getMonthDaysSafe(month, year) {
  const m = Number(month)
  if (!Number.isInteger(m) || m < 1 || m > 12) {
    throw new TypeError('Month must be an integer 1..12')
  }
  return getMonthDays(m, year)
}

Type guard

const isValidMonth = (m) => Number.isInteger(m) && m >= 1 && m <= 12

Try / catch

try { getMonthDays(month, year) } catch (e) { if (/Invalid Month/.test(e.message)) { /* prompt user, fix off-by-one */ } else throw e }

Prevention

When it happens

Trigger: Calling getMonthDays(0) (zero-based month from Date.getMonth()), getMonthDays(13), getMonthDays(-1), getMonthDays(2.5), getMonthDays('1') (string '1' is not === 1, rejected), getMonthDays(null) (not in sets, not === 2). getMonthDays(2) is accepted and routed to the leap-year branch.

Common situations: Forgetting that JavaScript Date.getMonth() returns 0–11 and passing its output directly; passing a month parsed from a string (parseInt is fine, but unconverted strings fail); off-by-one errors from UI dropdowns using 0-based indexing; negative or NaN values from failed parseInt.

Related errors


AI-assisted analysis of TheAlgorithms/JavaScript@5c39e87a9a (2026-08-13). Data as JSON: /api/errors/81aab950610f9526. Report an issue: GitHub.