alibaba/spring-cloud-alibaba · 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

Thrown in checkNext when 'W' (nearest weekday) is used in day-of-month but the preceding value exceeds 31 (guard at CronExpression.java:546-547). Since no month has more than 31 days, a 'W' anchor beyond 31 is nonsensical.

Solutions

  1. Use a day value 1-31 before 'W', e.g. '32W' -> '15W'.
  2. Range-check any injected day value before building the string.

Example fix

// before
new CronExpression("0 0 0 32W * ?");
// after
new CronExpression("0 0 0 15W * ?"); // nearest weekday to the 15th
Defensive patterns

Strategy: validation

Validate before calling

// '<n>W' in day-of-month requires n <= 31.
static boolean wAnchorOk(String domField) {
    if (!domField.endsWith("W") || domField.length() < 2) return true;
    try {
        int v = Integer.parseInt(domField.substring(0, domField.length() - 1));
        return v >= 1 && v <= 31;
    } catch (NumberFormatException e) { return false; }
}

Try / catch

try {
    CronExpression cron = new CronExpression(raw);
} catch (ParseException e) {
    throw new IllegalArgumentException("Invalid cron expression: " + raw, e);
}

Prevention

When it happens

Trigger: `new CronExpression("0 0 0 32W * ?")` (nearest weekday to the 32nd). Any '<n>W' in day-of-month with n > 31.

Common situations: Off-by-one or a value from another field concatenated before 'W'; also a templated day value that is not range-checked.

Related errors


AI-assisted analysis of alibaba/spring-cloud-alibaba@115d590110 (2026-08-14). Data as JSON: /api/errors/80a93196dfe924e6. Report an issue: GitHub.

Appendix: source

Thrown at spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-schedulerx/src/main/java/com/alibaba/cloud/scheduling/schedulerx/util/CronExpression.java:547

			}
			else {
				throw new ParseException("'L' option is not valid here. (pos=" + i + ")", i);
			}
			final TreeSet<Integer> set = getSet(type);
			set.add(val);
			i++;
			return i;
		}

		if (c == 'W') {
			if (type == DAY_OF_MONTH) {
				nearestWeekday = true;
			}
			else {
				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);
			}
			final TreeSet<Integer> set = getSet(type);
			set.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();
				}
			}

View on GitHub (pinned to 115d590110)