flowable/flowable-engine · error · FlowableIllegalArgumentException
Due date expression does not resolve to a Date, Instant, Loc
Error message
Due date expression does not resolve to a Date, Instant, LocalDate, LocalDateTime or Date string: + beforeContext.getDueDate()
What it means
The user task's flowable:dueDate expression resolved to an object whose type the engine cannot turn into a task due date. Only Date, Date-time (java.util.Date), String parseable as a date, Instant, LocalDate and LocalDateTime are accepted. A FlowableIllegalArgumentException is thrown when the expression evaluates to some other type.
Source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/UserTaskActivityBehavior.java:274
if (StringUtils.isNotEmpty(userTask.getBusinessCalendarName())) {
businessCalendarName = expressionManager.createExpression(userTask.getBusinessCalendarName()).getValue(execution).toString();
} else {
businessCalendarName = DueDateBusinessCalendar.NAME;
}
BusinessCalendar businessCalendar = processEngineConfiguration.getBusinessCalendarManager()
.getBusinessCalendar(businessCalendarName);
task.setDueDate(businessCalendar.resolveDuedate((String) dueDate));
} else if (dueDate instanceof Instant) {
task.setDueDate(Date.from((Instant) dueDate));
} else if (dueDate instanceof LocalDate) {
Date localDueDate = Date.from(((LocalDate) dueDate).atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
task.setDueDate(localDueDate);
} else if (dueDate instanceof LocalDateTime) {
Date localDueDate = Date.from(((LocalDateTime) dueDate).atZone(ZoneId.systemDefault()).toInstant());
task.setDueDate(localDueDate);
} else {
throw new FlowableIllegalArgumentException("Due date expression does not resolve to a Date, Instant, LocalDate, LocalDateTime or Date string: " + beforeContext.getDueDate());
}
}
}
}
protected void handlePriority(CreateUserTaskBeforeContext beforeContext, ExpressionManager expressionManager, TaskEntity task, DelegateExecution execution,
String activeTaskPriority) {
if (StringUtils.isNotEmpty(beforeContext.getPriority())) {
final Object priority = expressionManager.createExpression(beforeContext.getPriority()).getValue(execution);
if (priority != null) {
if (priority instanceof String) {
try {
task.setPriority(Integer.valueOf((String) priority));
} catch (NumberFormatException e) {
throw new FlowableIllegalArgumentException("Priority does not resolve to a number: " + priority, e);
}
} else if (priority instanceof Number) {
task.setPriority(((Number) priority).intValue());View on GitHub (pinned to d6d39ce1c6)
Solutions
- Change the expression/bean to return java.util.Date, Instant, LocalDate, LocalDateTime, or a date-String in an accepted format
- Convert ZonedDateTime/OffsetDateTime via toLocalDateTime() or Date.from(...) before returning it
- Set the process variable to the correct type before reaching the user task
- Fix the ISO date format of the String if returning text
- Wrap the logic in a delegate that normalizes the value
Example fix
// before
public ZonedDateTime getDueDate() { return ZonedDateTime.now().plusDays(2); }
// after
public Date getDueDate() { return Date.from(ZonedDateTime.now().plusDays(2).toInstant()); } Defensive patterns
Strategy: validation
Validate before calling
Object d = dueDateExpr.getValue(execution);
List<Class<?>> ok = List.of(Date.class, Instant.class, LocalDate.class, LocalDateTime.class, String.class);
if (d != null && ok.stream().noneMatch(c -> c.isInstance(d))) {
throw new IllegalArgumentException("dueDate type not supported: " + d.getClass());
} Type guard
boolean isValidDueDate(Object v) {
return v == null || v instanceof Date || v instanceof Instant
|| v instanceof LocalDate || v instanceof LocalDateTime || v instanceof String;
} Try / catch
try {
completeTask(taskId, vars);
} catch (FlowableIllegalArgumentException e) {
if (e.getMessage().startsWith("Due date expression")) {
// fix variable type and retry
}
} Prevention
- Use java.util.Date, Instant, LocalDate or LocalDateTime for dueDate values
- Do NOT use ZonedDateTime/OffsetDateTime
- Standardize date variables as ISO strings or Date objects
- Add an execution listener to normalize due-date variables before user tasks
When it happens
Trigger: flowable:dueDate expression like ${someVar} or ${bean.compute()} returning e.g. Integer, ZonedDateTime, OffsetDateTime, String in an unparseable format, or an unsupported object.
Common situations: Using ZonedDateTime/OffsetDateTime which are NOT supported (only LocalDate/LocalDateTime/Instant); expression returning a formatted String the date parser cannot read; passing a timestamp long from a variable; Spring bean method returning the wrong type.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Priority expression does not resolve to a number: + activeTa
- Due date expression does not resolve to a Date or Date strin
- Priority expression does not resolve to a number: %s
- Category expression does not resolve to a string: %s
- name expression does not resolve to a string:
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/d536cf8ffafcd406.
Report an issue: GitHub.