jeecgboot/JeecgBoot · error · IllegalArgumentException
Illegal month number: ${monthNum}
Error message
Illegal month number: ${monthNum} What it means
Thrown as IllegalArgumentException from getLastDayOfMonth when the monthNum parameter does not match any of the switch cases 1–12. This is a defensive guard in a method that returns the number of days in a given month (accounting for February leap years via a separate check). Under normal operation the monthNum always comes from validated cron data and is 1–12; this error indicates corrupted state or an unexpected code path feeding an invalid month.
Source
Thrown at jeecg-boot/jeecg-server-cloud/jeecg-visual/jeecg-cloud-xxljob/src/main/java/com/xxl/job/admin/business/scheduler/cron/CronExpression.java:1642
return 30;
case 5:
return 31;
case 6:
return 30;
case 7:
return 31;
case 8:
return 31;
case 9:
return 30;
case 10:
return 31;
case 11:
return 30;
case 12:
return 31;
default:
throw new IllegalArgumentException("Illegal month number: "
+ monthNum);
}
}
private Optional<Integer> findSmallestDay(int day, int mon, int year, TreeSet<Integer> set) {
if (set.isEmpty()) {
return Optional.empty();
}
final int lastDay = getLastDayOfMonth(mon, year);
// For "L", "L-1", etc.
final int smallestDay = Optional.ofNullable(set.ceiling(LAST_DAY_OFFSET_END - (lastDay - day)))
.map(d -> d - LAST_DAY_OFFSET_START + 1)
.orElse(Integer.MAX_VALUE);
// For "1", "2", etc.
SortedSet<Integer> st = set.subSet(day, LAST_DAY_OFFSET_START);View on GitHub (pinned to 96fb33f5ec)
Solutions
- If calling getLastDayOfMonth directly from custom code, validate monthNum is 1–12 before invoking.
- Ensure the cron expression's month field passed validation — check for error 311 in logs.
- Verify thread safety: CronExpression objects should not be shared across threads without synchronization if fields can change.
Example fix
// before int days = cronExpression.getLastDayOfMonth(0, 2024); // 0 is invalid // after int days = cronExpression.getLastDayOfMonth(1, 2024); // January
Defensive patterns
Strategy: try-catch
Validate before calling
if (monthNum < 1 || monthNum > 12) {
throw new IllegalArgumentException("Month must be 1-12, got: " + monthNum);
}
int days = cronExpression.getLastDayOfMonth(monthNum, year); Type guard
boolean isValidMonthNum(int monthNum) {
return monthNum >= 1 && monthNum <= 12;
} Try / catch
try {
int days = cronExpression.getLastDayOfMonth(mon, year);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Illegal month number")) {
// log and handle corrupted month state; reset CronExpression
}
throw e;
} Prevention
- Validate month values are 1–12 before calling getLastDayOfMonth.
- Ensure CronExpression objects are not shared unsafely across threads.
- Avoid reflective modification of internal cron field sets.
When it happens
Trigger: Internal call to getLastDayOfMonth with a value outside 1–12 — e.g., 0, 13, or a negative number. This would require the cron expression's month field to have bypassed the addToSet range check (error 311) or for month data to be corrupted in memory.
Common situations: Extremely rare in practice; could occur if the CronExpression object is modified reflectively, if a subclass overrides month handling, or if there is a concurrency issue where the TreeSet is modified during iteration. Most likely indicates a bug in custom code that calls getLastDayOfMonth directly.
Related errors
- Start year must be less than stop year
- Day-of-Week values must be between 1 and 7
- 'L' option is not valid here. (pos=${i})
- 'W' option is not valid here. (pos=${i})
- The 'W' option does not make sense with values larger than 3
AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14).
Data as JSON: /api/errors/143f3dc246ea041e.
Report an issue: GitHub.