flowable/flowable-engine · error · FlowableIllegalArgumentException

Converter can only convert string to localDate

Error message

Converter can only convert string to localDate

What it means

LocalDateRestVariableConverter.getVariableValue deserializes a REST variable into a java.time.LocalDate and requires the REST value to be a String. If the incoming value is any other type it throws FlowableIllegalArgumentException, because only ISO-8601 strings (e.g. "2026-09-10") can be parsed via LocalDate.parse.

Source

Thrown at modules/flowable-common-rest/src/main/java/org/flowable/common/rest/variable/LocalDateRestVariableConverter.java:39

 * @author Filip Hrisafov
 */
public class LocalDateRestVariableConverter implements RestVariableConverter {

    @Override
    public String getRestTypeName() {
        return "localDate";
    }

    @Override
    public Class<?> getVariableType() {
        return LocalDate.class;
    }

    @Override
    public Object getVariableValue(EngineRestVariable result) {
        if (result.getValue() != null) {
            if (!(result.getValue() instanceof String)) {
                throw new FlowableIllegalArgumentException("Converter can only convert string to localDate");
            }
            try {
                return LocalDate.parse((String) result.getValue());
            } catch (DateTimeParseException e) {
                throw new FlowableIllegalArgumentException("The given variable value is not a localDate: '" + result.getValue() + "'", e);
            }
        }
        return null;
    }

    @Override
    public void convertVariableValue(Object variableValue, EngineRestVariable result) {
        if (variableValue != null) {
            if (!(variableValue instanceof LocalDate)) {
                throw new FlowableIllegalArgumentException("Converter can only convert localDate");
            }
            result.setValue(variableValue.toString());
        } else {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Send the value as an ISO-8601 date string (yyyy-MM-dd) in the REST payload.
  2. Check the variable's type marker in the request matches localDate and the value field is a JSON string.
  3. If the client sends epoch millis or full datetimes, convert/trim them to yyyy-MM-dd strings client-side before posting.
  4. Fix client serialization config that renders LocalDate as arrays or numbers (e.g. Jackson WRITE_DATES_AS_TIMESTAMPS).

Example fix

// before
{ "type": "localDate", "value": 1757462400000 }

// after
{ "type": "localDate", "value": "2026-09-10" }
Defensive patterns

Strategy: validation

Validate before calling

if (!(rawValue instanceof String s)) {
    throw new IllegalArgumentException("localDate variable must be a JSON string, got: "
        + (rawValue == null ? "null" : rawValue.getClass().getSimpleName()));
}
LocalDate.parse(s); // fail fast on format before calling the API

Type guard

static boolean isIsoLocalDateString(Object v) {
    return v instanceof String s && s.matches("\\d{4}-\\d{2}-\\d{2}");
}

Try / catch

try {
    Object value = converter.getVariableValue(restVar);
} catch (FlowableIllegalArgumentException e) {
    // value was not a String or not a valid ISO date; inspect restVar.getValue()
    log.error("Invalid localDate variable: {}", restVar.getValue(), e);
}

Prevention

When it happens

Trigger: Sending a REST variable of type localDate whose JSON value is a number, boolean, array, object, or already-parsed date instead of a string, so result.getValue() is not a String when getVariableValue runs.

Common situations: Clients posting variables with unquoted JSON dates or epoch millis; REST frameworks deserializing dates into non-String types before the converter sees them; sending LocalDateTime or datetime-with-timezone strings to a localDate variable.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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