apache/dolphinscheduler · error · IllegalArgumentException
Cannot parse the expression:
Error message
Cannot parse the expression:
What it means
TimePlaceholderUtils.formatTimeExpression formats a time expression like $[add_months(yyyyMMdd,12*N)] against a given Date. It throws IllegalArgumentException('Cannot parse the expression: <expr>, date is null') when the supplied Date is null, because no baseline date exists to shift or format. (An empty expression with ignoreInvalidExpression=false throws the sibling 'Cannot format the date' error.)
Source
Thrown at dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/parser/TimePlaceholderUtils.java:273
return true;
} else if (ADD_STRING.equals(peek) && (ADD_STRING.equals(cur) || SUBTRACT_STRING.equals(cur))) {
return true;
} else {
return SUBTRACT_STRING.equals(peek) && (ADD_STRING.equals(cur) || SUBTRACT_STRING.equals(cur));
}
}
/**
* Format time expression with given date, the date cannot be null.
* <p> If the expression is not a time expression, return the original expression.
*
*/
public static String formatTimeExpression(final String timeExpression, final Date date,
final boolean ignoreInvalidExpression) {
// After N years: $[add_months(yyyyMMdd,12*N)], the first N months: $[add_months(yyyyMMdd,-N)], etc
if (date == null) {
throw new IllegalArgumentException("Cannot parse the expression: " + timeExpression + ", date is null");
}
if (StringUtils.isEmpty(timeExpression)) {
if (ignoreInvalidExpression) {
return timeExpression;
}
throw new IllegalArgumentException("Cannot format the date" + date + " with null timeExpression");
}
try {
if (timeExpression.startsWith(TIMESTAMP)) {
return calculateTimeStamp(timeExpression, date);
}
if (timeExpression.startsWith(YEAR_WEEK)) {
return calculateYearWeek(timeExpression, date);
}
return calcTimeExpression(timeExpression, date);
} catch (Exception e) {
if (ignoreInvalidExpression) {
return timeExpression;View on GitHub (pinned to 02eac45a1b)
Solutions
- Ensure the baseline date is computed before substitution (e.g. derive from schedule fire time via DateUtils) and never pass null.
- Guard the caller: if date == null, default to the workflow's scheduled time or now() depending on business semantics.
- For dependent tasks, verify the upstream task's finish time exists — it feeds the date used here.
- Catch IllegalArgumentException around formatTimeExpression only when ignoreInvalidExpression semantics are intended; otherwise let it fail loudly.
- Check the expression string too: an empty expression triggers the related error; validate non-empty before calling with ignoreInvalidExpression=false.
Example fix
// before String result = TimePlaceholderUtils.formatTimeExpression(expr, null, false); // after Date base = scheduleFireTime != null ? scheduleFireTime : new Date(); String result = TimePlaceholderUtils.formatTimeExpression(expr, base, false);
Defensive patterns
Strategy: type-guard
Validate before calling
if (date == null) { date = scheduleFireTime != null ? scheduleFireTime : new Date(); }
if (timeExpression == null || timeExpression.isEmpty()) { throw new IllegalArgumentException("empty time expression"); } Type guard
boolean canFormat(String expr, Date d) { return d != null && expr != null && !expr.isEmpty(); } Try / catch
try { out = TimePlaceholderUtils.formatTimeExpression(expr, baseDate, false); } catch (IllegalArgumentException e) { log.error("time expression failed: {}", expr, e); throw new TaskException("time placeholder substitution failed", e); } Prevention
- Always compute the schedule/fire date before placeholder substitution
- Pass the upstream task finish time for dependent scheduling, defaulting to now when absent
- Validate expressions non-empty before calling with ignoreInvalidExpression=false
- Unit-test time expressions against fixed dates to catch null-date regressions
When it happens
Trigger: Calling formatTimeExpression(timeExpression, null, false) — e.g. the scheduled/dependent fire time was not computed before placeholder substitution; a caller passes a null Date from a failed date calculation or from a parameter that was never set.
Common situations: Complement/dependent processing where the base schedule date is missing; calling the utility directly in custom plugins with an unset Date variable; a workflow triggered outside schedule context so the fire time is null.
Related errors
- backfillTime: ${backfillTime} is invalid
- Cannot format the date
- Unsupported placeholder expression:
- expression not valid
AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06).
Data as JSON: /api/errors/2ecafa86a7e0d012.
Report an issue: GitHub.