flowable/flowable-engine · error · ParseException

Support for specifying multiple "nth" days is not implemente

Error message

Support for specifying multiple "nth" days is not implemented.

What it means

buildExpression rejects a day-of-week field containing more than one '#' character. The '#' operator selects the nth weekday (e.g. FRI#3 = third Friday) and only a single nth-day selector per field is implemented. Thrown as ParseException from buildExpression.

Source

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

            StringTokenizer exprsTok = new StringTokenizer(expression, " \t", false);

            while (exprsTok.hasMoreTokens() && exprOn <= YEAR) {
                String expr = exprsTok.nextToken().trim();

                // throw an exception if L is used with other days of the month
                if (exprOn == DAY_OF_MONTH && expr.indexOf('L') != -1 && expr.length() > 1 && expr.contains(",")) {
                    throw new ParseException(
                            "Support for specifying 'L' and 'LW' with other days of the month is not implemented", -1);
                }
                // throw an exception if L is used with other days of the week
                if (exprOn == DAY_OF_WEEK && expr.indexOf('L') != -1 && expr.length() > 1 && expr.contains(",")) {
                    throw new ParseException(
                            "Support for specifying 'L' with other days of the week is not implemented", -1);
                }
                if (exprOn == DAY_OF_WEEK && expr.indexOf('#') != -1
                        && expr.indexOf('#', expr.indexOf('#') + 1) != -1) {
                    throw new ParseException("Support for specifying multiple \"nth\" days is not implemented.", -1);
                }

                StringTokenizer vTok = new StringTokenizer(expr, ",");
                while (vTok.hasMoreTokens()) {
                    String v = vTok.nextToken();
                    storeExpressionVals(0, v, exprOn);
                }

                exprOn++;
            }

            if (exprOn <= DAY_OF_WEEK) {
                throw new ParseException("Unexpected end of expression.", expression.length());
            }

            if (exprOn <= YEAR) {
                storeExpressionVals(0, "*", YEAR);
            }

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Keep at most one '#N' selector in the day-of-week field
  2. Split into multiple timer/job definitions, one per nth-day rule
  3. Replace with explicit dates in day-of-month if the occurrences are computable in advance

Example fix

// before
String cron = "0 0 12 ? * MON#1,FRI#3"; // unsupported
// after
String cron1 = "0 0 12 ? * MON#1"; // and a second timer with "0 0 12 ? * FRI#3"
Defensive patterns

Strategy: validation

Validate before calling

String dow = fields[5];
if (dow.indexOf('#') != dow.lastIndexOf('#')) throw new IllegalArgumentException("only one nth-day (#) selector allowed in day-of-week");

Try / catch

try { new CronExpression(expr, clockReader); }
catch (ParseException e) { if (e.getMessage().contains("nth\" days")) { /* split the expression */ } throw e; }

Prevention

When it happens

Trigger: new CronExpression(expr, clockReader) where the day-of-week field contains two or more '#' occurrences, e.g. '0 0 12 ? * MON#1,FRI#3'.

Common situations: Trying to express 'first Monday and third Friday' in one cron expression; translating schedules from cron tools that allow multiple nth selectors; misunderstanding that ',' combines whole alternatives rather than multiple '#' specs.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/fb2518162c6c92fe. Report an issue: GitHub.