xuxueli/xxl-job · error · ParseException

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

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.

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.

Appendix: 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)