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: 

What it means

The due date attribute expression resolved to an object of an unsupported type. Flowable accepts java.util.Date, Instant, LocalDate, LocalDateTime, or a String parseable as a date; anything else (Calendar, ZonedDateTime, custom type) is rejected with FlowableIllegalArgumentException enumerating the accepted types.

Source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/behavior/impl/HumanTaskActivityBehavior.java:349

                    taskEntity.setDueDate((Date) dueDate);

                } else if (dueDate instanceof String dueDateString) {
                    Date resolvedDuedate = CommandContextUtil.getCmmnEngineConfiguration(commandContext).getBusinessCalendarManager()
                            .getBusinessCalendar(DueDateBusinessCalendar.NAME)
                            .resolveDuedate(dueDateString);
                    taskEntity.setDueDate(resolvedDuedate);

                } else if (dueDate instanceof Instant) {
                    taskEntity.setDueDate(Date.from((Instant) dueDate));

                } else if (dueDate instanceof LocalDate) {
                    taskEntity.setDueDate(Date.from(((LocalDate) dueDate).atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));

                }  else if (dueDate instanceof LocalDateTime) {
                    taskEntity.setDueDate(Date.from(((LocalDateTime) dueDate).atZone(ZoneId.systemDefault()).toInstant()));

                } else {
                    throw new FlowableIllegalArgumentException("Due date expression does not resolve to a Date, Instant, LocalDate, LocalDateTime or Date string: " + beforeContext.getDueDate());
                }
            }
        }
    }

    protected void handleCategory(PlanItemInstanceEntity planItemInstanceEntity, ExpressionManager expressionManager,
            TaskEntity taskEntity, CreateHumanTaskBeforeContext beforeContext, MigrationContext migrationContext) {
        
        String categoryStringValue = null;
        if (migrationContext != null && migrationContext.getCategory() != null) {
            categoryStringValue = migrationContext.getCategory();
            
        } else if (StringUtils.isNotEmpty(beforeContext.getCategory())) {
            categoryStringValue = beforeContext.getCategory();
        }
        
        if (StringUtils.isNotEmpty(categoryStringValue)) {
            final Object category = expressionManager.createExpression(categoryStringValue).getValue(planItemInstanceEntity);

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Normalize the variable to java.util.Date or LocalDateTime before the plan item executes.
  2. If it is ZonedDateTime/OffsetDateTime, convert: Date.from(zdt.toInstant()) when setting the variable.
  3. If it is a String, use a format Flowable can parse (e.g. ISO-8601 yyyy-MM-dd or full date-time) or provide a java.util.Date.
  4. Catch FlowableIllegalArgumentException and log beforeContext.getDueDate() plus the value's class to identify the offending type.

Example fix

// before
execution.setVariable("dueDate", ZonedDateTime.now().plusDays(2));
// after
execution.setVariable("dueDate", Date.from(ZonedDateTime.now().plusDays(2).toInstant()));
Defensive patterns

Strategy: type-guard

Validate before calling

Object d = variableScope.getVariable("dueDate");
boolean ok = d == null || d instanceof java.util.Date || d instanceof java.time.Instant
    || d instanceof java.time.LocalDate || d instanceof java.time.LocalDateTime;
if (!ok) throw new IllegalArgumentException("dueDate must be Date, Instant, LocalDate or LocalDateTime, got " + (d == null ? "null" : d.getClass()));

Type guard

boolean isValidDueDate(Object v) { return v == null || v instanceof java.util.Date || v instanceof java.time.Instant || v instanceof java.time.LocalDate || v instanceof java.time.LocalDateTime; }

Try / catch

try {
    // execute human task
} catch (FlowableIllegalArgumentException e) {
    if (e.getMessage().startsWith("Due date expression")) {
        log.error("Unsupported due date type: {}", e.getMessage());
    }
}

Prevention

When it happens

Trigger: HumanTaskActivityBehavior.execute -> handleDueDate, when the dueDate expression returns a non-null object failing all accepted instanceof branches (Date, Instant, LocalDate, LocalDateTime, String).

Common situations: Variable is a ZonedDateTime/OffsetDateTime or java.sql.Timestamp subclass branch not handled; expression returns a Date-formatted display String with a locale-specific pattern the parser cannot read; JS/ Groovy evaluation returning a wrapped type.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/2017dde4cb3670e3. Report an issue: GitHub.