xuxueli/xxl-job · error · ParseException

The 'W' option does not make sense with values larger than 3

Error message

The 'W' option does not make sense with values larger than 31 (max number of days in a month)

What it means

In checkNext, the 'W' (nearest weekday) modifier in the Day-of-Month field requires the preceding numeric value to be 31 or less, since no month has more than 31 days. This error fires when val > 31.

Source

Thrown at xxl-job-admin/src/main/java/com/xxl/job/admin/business/scheduler/cron/CronExpression.java:772

            if (type == DAY_OF_WEEK) {
                if(val < 1 || val > 7)
                    throw new ParseException("Day-of-Week values must be between 1 and 7", -1);
                lastDayOfWeek = true;
            } else {
                throw new ParseException("'L' option is not valid here. (pos=" + i + ")", i);
            }
            TreeSet<Integer> set = getSet(type);
            set.add(val);
            i++;
            return i;
        }

        if (c == 'W') {
            if (type != DAY_OF_MONTH) {
                throw new ParseException("'W' option is not valid here. (pos=" + i + ")", i);
            }
            if(val > 31)
                throw new ParseException("The 'W' option does not make sense with values larger than 31 (max number of days in a month)", i);
            nearestWeekdays.add(val);
            i++;
            return i;
        }

        if (c == '#') {
            if (type != DAY_OF_WEEK) {
                throw new ParseException("'#' option is not valid here. (pos=" + i + ")", i);
            }
            i++;
            try {
                nthDayOfWeek = Integer.parseInt(s.substring(i));
                if (nthDayOfWeek < 1 || nthDayOfWeek > 5) {
                    throw new Exception();
                }
            } catch (Exception e) {
                throw new ParseException(
                        "A numeric value between 1 and 5 must follow the '#' option",

View on GitHub (pinned to e74c784f68)

Solutions

  1. Reduce the day-of-month value to 31 or less before 'W'.
  2. Validate the value against the 1-31 range before constructing the expression.
  3. If the intent is the last weekday of the month, use 'LW' instead of a large number.

Example fix

// before
"0 0 0 32W * ?"
// after
"0 0 0 15W * ?"
Defensive patterns

Strategy: validation

Validate before calling

// Check 'NW' value in day-of-month (field index 3) is <= 31
String[] parts = cron.trim().split("\\s+");
if (parts.length > 3 && parts[3].matches(".*\\d+W.*")) {
    String numPart = parts[3].replaceAll("W.*", "").replaceAll(".*[^0-9]", "");
    if (!numPart.isEmpty()) {
        int val = Integer.parseInt(numPart);
        if (val > 31) throw new IllegalArgumentException("'W' value must be <= 31: " + val);
    }
}

Type guard

boolean isValidNearestWeekdayValue(String domField) {
    if (!domField.contains("W")) return true;
    String num = domField.replaceAll("W.*", "").replaceAll(".*[^0-9]", "");
    if (num.isEmpty()) return true;
    return Integer.parseInt(num) <= 31;

Try / catch

try {
    new CronExpression(cron);
} catch (ParseException e) {
    if (e.getMessage().contains("'W' option does not make sense")) {
        // reduce the day value to 31 or less, or use 'LW' for last weekday
    }
}

Prevention

When it happens

Trigger: A cron expression like '0 0 0 32W * ?' where the value before 'W' in the day-of-month field exceeds 31. The check at line 771 tests val > 31.

Common situations: Generating a day-of-month value dynamically without clamping, or a typo/overflow producing a value beyond 31.

Related errors


AI-assisted analysis of xuxueli/xxl-job@e74c784f68 (2026-08-14). Data as JSON: /api/errors/e66d697eed5155a1. Report an issue: GitHub.