flowable/flowable-engine · error · FlowableException
Couldn't serialize value
Error message
Couldn't serialize value '${value}' in variable '${name}' What it means
Flowable's SerializableType serializes a variable value to bytes via Java ObjectOutputStream before persisting it. This FlowableException wraps any exception thrown during writeObject (NotSerializableException, IOException, etc.), naming the value and the variable. It means the value stored in the variable cannot be Java-serialized.
Solutions
- Make the variable's class (and every object it references transitively) implement java.io.Serializable
- Store only small, serializable data (ids, JSON strings) in variables instead of live objects; re-fetch objects in delegates
- Inspect the cause: NotSerializableException names the first offending class — fix that class or mark the field transient
- If the object is huge or non-serializable by design, keep it out of the variable scope (pass via external store and put only the key in the variable)
Example fix
// before runtimeService.setVariable(executionId, "customer", new CustomerService()); // after runtimeService.setVariable(executionId, "customerId", customer.getId());
Defensive patterns
Strategy: try-catch
Validate before calling
private static boolean isSerializable(Object o) {
if (o instanceof Serializable) return true;
try { new ObjectOutputStream(new ByteArrayOutputStream()).writeObject(o); return true; }
catch (NotSerializableException e) { return false; }
catch (IOException e) { return false; }
} Type guard
if (!(value instanceof java.io.Serializable)) {
throw new IllegalArgumentException("Variable value must implement Serializable: " + value.getClass());
} Try / catch
try {
runtimeService.setVariable(executionId, name, value);
} catch (FlowableException e) {
if (e.getCause() instanceof NotSerializableException) {
log.error("Variable {} value not serializable: {}", name, e.getCause().getMessage());
}
throw e;
} Prevention
- Only store primitives, Strings, and explicit Serializable DTOs in process variables
- Run a unit test that serializes every domain class used as a variable value
- Mark non-serializable fields transient and re-resolve them after deserialization
- Store large objects externally and keep only the key in the variable
When it happens
Trigger: Setting a process/execution/task variable (or a transient variable) whose runtime type does not implement java.io.Serializable, or whose fields reference non-serializable objects; serialization stream corruption or a custom writeObject throwing; createObjectOutputStream failing.
Common situations: Putting a Spring service bean, an InputStream/Connection, a lambda capturing a non-serializable context, or a Mockito mock into a process variable; an object graph that gained a non-serializable field after a dependency upgrade.
Understand the failure class
Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.
Related errors
- couldn't find a variable type that is able to serialize
- Couldn't serialize value '' in variable ''
- Couldn't deserialize object in variable
- Empty object, no variables can be set
- Error getting variable
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/90270a4cc89f6a24.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-variable-service/src/main/java/org/flowable/variable/service/impl/types/SerializableType.java:146
if (!Arrays.equals(refreshedOriginalBytes, bytes)) {
variableInstanceEntity.setBytes(bytes);
valueChanged = true;
}
}
return valueChanged;
}
public byte[] serialize(Object value, ValueFields valueFields) {
if (value == null) {
return null;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = null;
try {
oos = createObjectOutputStream(baos);
oos.writeObject(value);
} catch (Exception e) {
throw new FlowableException("Couldn't serialize value '" + value + "' in variable '" + valueFields.getName() + "'", e);
} finally {
IoUtil.closeSilently(oos);
}
return baos.toByteArray();
}
public Object deserialize(byte[] bytes, ValueFields valueFields) {
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
try {
ObjectInputStream ois = createObjectInputStream(bais);
Object deserializedObject = ois.readObject();
return deserializedObject;
} catch (Exception e) {
throw new FlowableException("Couldn't deserialize object in variable '" + valueFields.getName() + "'", e);
} finally {
IoUtil.closeSilently(bais);
}View on GitHub (pinned to d6d39ce1c6)