Activiti/Activiti · 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

This library's cron parser (a port of Quartz's CronExpression) supports the 'W' suffix on a day-of-month field, meaning 'nearest weekday to the given day'. The value preceding 'W' must be a valid day of a month. Since no month has more than 31 days, any value above 31 is rejected at parse time with a ParseException.

Solutions

  1. Correct the day-of-month value before 'W' to a number between 1 and 31.
  2. If the intent was 'last day of the month', use 'L' instead of an over-large 'W' value.
  3. Validate the cron string (or bound the user-supplied day value to 1..31) before constructing the CronExpression.

Example fix

// before
String cron = "0 0 0 45W * ?";
CronExpression ce = new CronExpression(cron);
// after
String cron = "0 0 0 15W * ?"; // 15W: nearest weekday to the 15th
CronExpression ce = new CronExpression(cron);
Defensive patterns

Strategy: validation

Validate before calling

int dayVal = extractDayOfMonthBeforeW(cron); // parse token yourself
if (dayVal > 31) throw new IllegalArgumentException("'W' day-of-month must be 1-31");

Type guard

boolean isValidWeekdaySpec(String token) {
    int i = token.indexOf('W');
    if (i < 1) return true;
    try { return Integer.parseInt(token.substring(0, i)) <= 31; }
    catch (NumberFormatException e) { return false; }
}

Try / catch

try {
    CronExpression ce = new CronExpression(cron);
} catch (ParseException e) {
    if (e.getMessage().contains("'W' option")) {
        throw new ConfigurationException("Invalid day-of-month 'W' value in cron: " + cron, e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Parsing a cron expression whose DAY_OF_MONTH token ends with 'W' and has a numeric value greater than 31 (e.g. '0 0 0 45W * ?' or '0 0 0 32W * ?'), via storeExpressionVals during CronExpression construction.

Common situations: Typo or hand-edited cron string in a timer boundary event or job definition in an Activiti BPMN process; a generated expression built from user input without range validation; copy-paste from another scheduler dialect with different day-of-month semantics.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of Activiti/Activiti@56435b1a97 (2026-09-09). Data as JSON: /api/errors/9f5c8fb4435849c4. Report an issue: GitHub.

Appendix: source

Thrown at activiti-core/activiti-engine/src/main/java/org/activiti/engine/impl/calendar/CronExpression.java:581

            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(Integer.valueOf(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
            );
            TreeSet<Integer> set = getSet(type);
            set.add(Integer.valueOf(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 56435b1a97)