jeecgboot/JeecgBoot · error · ParseException
Unexpected end of expression.
Error message
Unexpected end of expression.
What it means
Thrown by CronExpression's parser when the expression has fewer than 6 fields after tokenization completes. The parser tracks which field it has processed via exprOn (starting at SECOND=1 through YEAR=7). If after consuming all tokens, exprOn is still at or below DAY_OF_WEEK (field 5), the expression is too short. A valid Quartz cron requires at least 6 fields (seconds through day-of-week). The error position is set to the expression length.
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:507
// 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);
}
TreeSet<Integer> dow = getSet(DAY_OF_WEEK);
TreeSet<Integer> dom = getSet(DAY_OF_MONTH);
// Copying the logic from the UnsupportedOperationException below
boolean dayOfMSpec = !dom.contains(NO_SPEC);
boolean dayOfWSpec = !dow.contains(NO_SPEC);
if (!dayOfMSpec || dayOfWSpec) {
if (!dayOfWSpec || dayOfMSpec) {
throw new ParseException(
"Support for specifying both a day-of-week AND a day-of-month parameter is not implemented.", 0);View on GitHub (pinned to 96fb33f5ec)
Solutions
- Ensure the expression has at least 6 fields: add a leading seconds field (usually '0') to 5-field Unix cron expressions.
- Convert Unix '0 6 * * *' to Quartz '0 0 6 * * ?' (note: also change '*' in day-of-week to '?').
- Validate field count before constructing the CronExpression: split by whitespace and assert length is 6 or 7.
- Check for template/variable substitution issues that may truncate the expression.
Example fix
// before: 5-field Unix cron (missing seconds field) String cron = "0 6 * * *"; CronExpression expr = new CronExpression(cron); // after: 6-field Quartz cron (seconds minutes hours dom month dow) String cron = "0 0 6 * * ?"; CronExpression expr = new CronExpression(cron);
Defensive patterns
Strategy: validation
Validate before calling
// Validate minimum field count before parsing
public void validateCronMinFields(String expression) {
if (expression == null || expression.trim().isEmpty()) {
throw new IllegalArgumentException("Cron expression cannot be null or empty");
}
int count = new StringTokenizer(expression, " \t").countTokens();
if (count < 6) {
throw new IllegalArgumentException(
"Cron expression must have at least 6 fields (seconds through day-of-week), found " + count);
}
} Type guard
// Check expression has at least 6 whitespace-separated fields
public boolean hasMinCronFields(String expression) {
if (expression == null || expression.trim().isEmpty()) return false;
return new StringTokenizer(expression, " \t").countTokens() >= 6;
} Try / catch
try {
CronExpression cron = new CronExpression(expression);
} catch (ParseException e) {
if (e.getMessage().contains("Unexpected end")) {
throw new IllegalArgumentException(
"Cron expression is too short. Quartz requires at least 6 fields (add a seconds field).", e);
}
throw e;
} Prevention
- Always include the seconds field when writing Quartz cron expressions.
- Convert 5-field Unix cron to 6-field Quartz cron by prepending '0' for seconds.
- Validate field count programmatically before constructing a CronExpression.
- Check for template/variable substitution issues that may truncate the expression.
When it happens
Trigger: Providing a 5-field Unix-style cron expression like '0 6 * * *' (no seconds field). Providing a partial expression like '0 0 12 * *' (only 5 fields). Empty or whitespace-only string passed as the cron expression. An expression with only 1-4 fields due to a copy-paste truncation.
Common situations: Using standard Linux crontab syntax (5 fields) which Quartz does not accept — Quartz requires a leading seconds field. Truncated expression from string manipulation or template substitution failure. Copying a cron expression from a non-Quartz system. Variable interpolation that produces fewer fields than expected.
Related errors
- Invalid expression has too many terms: {expression}
- Support for specifying 'L' with other days of the week is no
- Support for specifying multiple "nth" days is not implemente
- Support for specifying both a day-of-week AND a day-of-month
- Illegal cron expression format ({e})
AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14).
Data as JSON: /api/errors/2795a4fa79d4be5d.
Report an issue: GitHub.