flowable/flowable-engine · error · ParseException

A numeric value between 1 and 5 must follow the '#' option

Error message

A numeric value between 1 and 5 must follow the '#' option

What it means

Thrown when the Day-of-Week field uses the nth-day syntax 'day#n' and the value after '#' is not an integer between 1 and 5. In Quartz-style cron 'FRI#3' means 'the 3rd Friday of the month'; n must be 1-5. The parser catches any Exception from Integer.parseInt or the range check and rethrows this ParseException.

Source

Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/calendar/CronExpression.java:594

                }
                if (s.length() > i + 3) {
                    c = s.charAt(i + 3);
                    if (c == '-') {
                        i += 4;
                        sub = s.substring(i, i + 3);
                        eval = getDayOfWeekNumber(sub);
                        if (eval < 0) {
                            throw new ParseException("Invalid Day-of-Week value: '" + sub + "'", i);
                        }
                    } else if (c == '#') {
                        try {
                            i += 4;
                            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", i);
                        }
                    } else if (c == 'L') {
                        lastdayOfWeek = true;
                        i++;
                    }
                }

            } else {
                throw new ParseException("Illegal characters for this position: '" + sub + "'", i);
            }
            if (eval != -1) {
                incr = 1;
            }
            addToSet(sval, eval, incr, type);
            return (i + 3);
        }

        if (c == '?') {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Use a value between 1 and 5 after '#': e.g. 'MON#1' = first Monday of the month.
  2. Clamp/validate the nth value programmatically before composing the expression string.
  3. If you need 'last day-of-week of the month', use the 'L' option instead (e.g. 'FRIL' or '6L').
  4. Wrap construction in try-catch on ParseException to surface a user-friendly message about the '#' syntax.

Example fix

// before
new CronExpression("0 0 12 ? * FRI#0");
// after
new CronExpression("0 0 12 ? * FRI#1");
Defensive patterns

Strategy: validation

Validate before calling

java.util.regex.Matcher m = java.util.regex.Pattern.compile("#(\\d+)").matcher(expr);
if (m.find()) {
    int n = Integer.parseInt(m.group(1));
    if (n < 1 || n > 5) throw new IllegalArgumentException("'#' nth must be 1-5, got " + n);
}

Try / catch

try {
    new CronExpression(expr);
} catch (java.text.ParseException e) {
    throw new IllegalArgumentException("Invalid '#' nth-day syntax in cron: " + expr, e);
}

Prevention

When it happens

Trigger: new CronExpression("0 0 12 ? * FRI#0"), "FRI#6", "FRI#" (nothing after #), "FRI#three" — any nthdayOfWeek < 1 or > 5 or non-numeric remainder after '#'.

Common situations: Copy-pasting cron from generators that emit '#6' or '#0'; assuming the '#' value is 0-based; leaving a stray '#' with no number; expressions built dynamically where the nth variable falls outside 1-5.

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 flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/0a158a72f9f6ac49. Report an issue: GitHub.