flowable/flowable-engine · error · ParseException
'#' option is not valid here. (pos=
Error message
'#' option is not valid here. (pos=
What it means
The cron expression parser in Flowable's CronExpression (a Quartz-derived parser) found a '#' character, which is only allowed in the day-of-week field to mean 'the nth weekday of the month' (e.g. 'FRI#3'). A '#' appearing in any other field (second, minute, hour, day-of-month, month, year) is syntactically invalid there, so a ParseException is thrown during storeExpressionVals/checkNext. This happens at expression-parse time, before any scheduling occurs.
Source
Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/calendar/CronExpression.java:769
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(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", i);
}
TreeSet<Integer> set = getSet(type);
set.add(val);
i++;
return i;
}
if (c == '-') {View on GitHub (pinned to d6d39ce1c6)
Solutions
- Move the '#' nth-weekday clause into the day-of-week field, e.g. '0 0 0 ? * FRI#3' instead of placing it elsewhere
- Remove the '#' if it was intended as a comment — cron strings here do not support inline comments; place comments outside the expression
- Validate the cron expression with CronExpression.isValidExpression(expr) before feeding it to the engine to fail fast with a clearer message
- Count the fields: a Quartz-style cron has 6 or 7 fields (second minute hour day-of-month month [day-of-week] [year]); ensure each token sits in the right position
Example fix
// before
CronExpression cron = new CronExpression("0 0 15#2 * *"); // '#' in hour field
// after
CronExpression cron = new CronExpression("0 0 0 ? * FRI#2"); // nth-Friday in day-of-week field Defensive patterns
Strategy: validation
Validate before calling
String expr = "0 0 0 ? * FRI#2";
String dow = expr.split("\\s+")[5];
if (expr.contains("#") && !dow.contains("#")) {
throw new IllegalArgumentException("'#' may only appear in the day-of-week field: " + expr);
}
if (!org.flowable.common.engine.impl.calendar.CronExpression.isValidExpression(expr)) {
throw new IllegalArgumentException("Invalid cron expression: " + expr);
} Try / catch
try {
CronExpression cron = new CronExpression(expr);
} catch (ParseException e) {
log.error("Bad cron expression at position {}: {}", e.getErrorOffset(), e.getMessage());
throw new ConfigurationException("Invalid cron expression: " + expr, e);
} Prevention
- Only use '#' in the day-of-week field (6th field of a Quartz cron)
- Run CronExpression.isValidExpression(expr) on every expression before use, especially user- or config-supplied ones
- Never place shell-style '#' comments inside a cron string
- Show a field-position diagram in any UI that lets users author cron expressions
When it happens
Trigger: Calling new CronExpression(expr) or passing a cron string to Flowable configuration (e.g. process/timer definitions) where a '#' appears outside the day-of-week field — e.g. '0 0 15#1 * *' or a '#' accidentally placed in the day-of-month field.
Common situations: Copy-pasted cron expressions from systems with different cron dialects (some allow different token positions); hand-edited expressions where '#' was meant for day-of-week but shifted into day-of-month; typo or leftover shell-comment '#' inside the expression (classic crontab files allow # comments, but an inline comment within the 6-7 field cron string is invalid).
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Unexpected character '<c>' after '/'
- Minute and Second values must be between 0 and 59
- Hour values must be between 0 and 23
- Day of month values must be between 1 and 31
- Month values must be between 1 and 12
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/f12414f3452b4089.
Report an issue: GitHub.