jeecgboot/JeecgBoot · 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
Thrown by CronExpression's parser when the day-of-week field contains more than one '#' character — e.g., 'FRI#2,FRI#4' or '6#1,6#3'. The '#' modifier specifies the 'nth occurrence' of a day in a month (e.g., '6#3' = third Friday). Quartz does not support multiple nth-day specifiers in a single expression. The check detects a second '#' after the first one in the field.
Source
Thrown at jeecg-boot/jeecg-server-cloud/jeecg-visual/jeecg-cloud-xxljob/src/main/java/com/xxl/job/admin/business/scheduler/cron/CronExpression.java:494
int exprOn = SECOND;
StringTokenizer exprsTok = new StringTokenizer(expression, " \t",
false);
if(exprsTok.countTokens() > 7) {
throw new ParseException("Invalid expression has too many terms: " + expression, -1);
}
while (exprsTok.hasMoreTokens() && exprOn <= YEAR) {
String expr = exprsTok.nextToken().trim();
// 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 96fb33f5ec)
Solutions
- Split into multiple CronTriggers: one for '6#1' (first Friday) and another for '6#3' (third Friday), both targeting the same job.
- If the schedule can be expressed as 'every N weeks', consider using a different scheduling strategy (e.g., a simple periodic trigger with date filtering).
- Use '6#1' alone if only one nth-occurrence is needed: '0 0 12 ? * 6#1'.
Example fix
// before: multiple # specifiers in one expression — invalid
String cron = "0 0 12 ? * 6#1,6#3";
CronExpression expr = new CronExpression(cron);
// after: two separate triggers
CronTrigger firstFriday = TriggerBuilder.newTrigger()
.withSchedule(CronScheduleBuilder.cronSchedule("0 0 12 ? * 6#1"))
.build();
CronTrigger thirdFriday = TriggerBuilder.newTrigger()
.withSchedule(CronScheduleBuilder.cronSchedule("0 0 12 ? * 6#3"))
.build();
scheduler.scheduleJob(jobDetail, firstFriday);
scheduler.scheduleJob(jobDetail, thirdFriday); Defensive patterns
Strategy: validation
Validate before calling
// Pre-validate day-of-week field for multiple # specifiers
public void validateDayOfWeekField(String cronExpression) {
String[] fields = cronExpression.trim().split("\\s+");
if (fields.length >= 6) {
String dayOfWeek = fields[5];
int hashCount = dayOfWeek.length() - dayOfWeek.replace("#", "").length();
if (hashCount > 1) {
throw new IllegalArgumentException(
"Cannot specify multiple '#' nth-day modifiers: " + dayOfWeek);
}
}
} Type guard
// Check if day-of-week field has at most one # specifier
public boolean hasValidNthDaySpecifier(String dow) {
if (dow == null || dow.isEmpty()) return true;
int hashCount = dow.length() - dow.replace("#", "").length();
return hashCount <= 1;
} Try / catch
try {
CronExpression cron = new CronExpression(expression);
} catch (ParseException e) {
if (e.getMessage().contains("nth")) {
throw new IllegalArgumentException(
"Multiple '#' specifiers are not supported. Split into separate triggers.", e);
}
throw e;
} Prevention
- Use at most one '#' specifier per cron expression (e.g., '6#3' for third Friday only).
- For multiple nth-occurrence rules (e.g., first AND third Friday), create separate triggers.
- Validate cron expressions in the admin UI before saving to prevent runtime parse errors.
- Educate users on Quartz '#' modifier semantics: dayOfWeek#nthOccurrence.
When it happens
Trigger: Cron expression like '0 0 12 ? * 6#1,6#3' trying to run on the first and third Friday of each month. Expression like '0 0 6 ? * 1#1,1#3' for first and third Sunday. Any comma-separated day-of-week value containing two or more '#' characters.
Common situations: Scheduling bi-weekly or specific-week-of-month jobs that need multiple nth-occurrence rules. Misunderstanding that '#' can only appear once per expression. Building dynamic cron strings that concatenate multiple '#'-based rules.
Related errors
- Support for specifying 'L' with other days of the week is no
- Support for specifying both a day-of-week AND a day-of-month
- Invalid expression has too many terms: {expression}
- Unexpected end of expression.
- Invalid Day-of-Week value: '{sub}'
AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14).
Data as JSON: /api/errors/19b28160d769320e.
Report an issue: GitHub.