flowable/flowable-engine · error · FlowableIllegalArgumentException
Converter can only convert string to instant
Error message
Converter can only convert string to instant
What it means
InstantRestVariableConverter.getVariableValue parses a String into java.time.Instant using Instant.parse (ISO-8601 instant format). If the stored value is non-null but not a String, it throws this FlowableIllegalArgumentException because only strings can be parsed.
Source
Thrown at modules/flowable-common-rest/src/main/java/org/flowable/common/rest/variable/InstantRestVariableConverter.java:39
* @author Filip Hrisafov
*/
public class InstantRestVariableConverter implements RestVariableConverter {
@Override
public String getRestTypeName() {
return "instant";
}
@Override
public Class<?> getVariableType() {
return Instant.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 instant");
}
try {
return Instant.parse((String) result.getValue());
} catch (DateTimeParseException e) {
throw new FlowableIllegalArgumentException("The given variable value is not an instant: '" + result.getValue() + "'", e);
}
}
return null;
}
@Override
public void convertVariableValue(Object variableValue, EngineRestVariable result) {
if (variableValue != null) {
if (!(variableValue instanceof Instant)) {
throw new FlowableIllegalArgumentException("Converter can only convert instant");
}
result.setValue(variableValue.toString());
} else {View on GitHub (pinned to d6d39ce1c6)
Solutions
- Request the variable with the REST type matching the stored value (e.g. 'date' for java.util.Date).
- Store the variable as an ISO-8601 instant string (e.g. 2026-09-10T00:00:00Z).
- Convert the value with Instant.toString() before storing if custom code populates it.
- Check for converter type-name collisions in the REST variable converter registry.
Example fix
// before runtimeService.setVariable(executionId, "firedAt", new Date()); // served via instant converter // after runtimeService.setVariable(executionId, "firedAt", Instant.now().toString());
Defensive patterns
Strategy: type-guard
Validate before calling
public static boolean isInstantString(Object v) { return v == null || v instanceof String; } Type guard
public static boolean isString(Object v) { return v instanceof String; } Try / catch
try {
Object ts = restClient.getVariable(id, "firedAt");
} catch (FlowableIllegalArgumentException e) {
if (e.getMessage().equals("Converter can only convert string to instant")) {
// request the variable with the correct REST type or re-store as ISO string
} else { throw e; }
} Prevention
- Store instant variables as ISO-8601 strings or as java.time.Instant with a matching converter.
- Match the requested REST type ('instant' vs 'date') to the stored Java type.
- Avoid mixing Date and Instant conventions across services.
When it happens
Trigger: Reading a REST variable typed as 'instant' when the engine value is not a String (e.g. java.util.Date, Instant object, or number).
Common situations: Variable stored by the engine as Date but served through the instant converter; custom code setting the variable as an Instant object; type name mismatch between stored and requested REST type.
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
- Converter can only convert instant
- Converter can only convert booleans
- Converter can only convert doubles
- Converter can only convert integers
- Variable '${restVariable.getName()}' has unsupported type: '
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/eeed8d88c64d386c.
Report an issue: GitHub.