flowable/flowable-engine · error · FlowableException
Cannot aggregate overview variable
Error message
Cannot aggregate overview variable: ${varInstance} What it means
JsonVariableAggregator.aggregateSingleVariable merges variable instances into a JSON object. In OVERVIEW state it can only include values that are JSON nodes; when a variable instance's value is not recognized as a JSON node (per the configured JsonMapper) it throws this exception instead of silently aggregating it.
Solutions
- Ensure all variables targeted for aggregation are stored as JSON (set them as JSON strings/nodes via JsonUtil or the flowable JSON variable type)
- Check the ProcessEngineConfiguration's JsonMapper / variable type configuration so JSON variables are recognized by isJsonNode
- Exclude non-JSON variables from the aggregation target variable name (targetVarName) so the aggregator never sees them
- Add a conversion step in the delegate to serialize the value into a Flowable JSON node before storing it
Example fix
// before
execution.setVariable("childResult", new MyPojo());
// after
execution.setVariable("childResult",
JsonUtil.getFlowableJsonNode(objectMapper.valueToTree(new MyPojo()))); Defensive patterns
Strategy: type-guard
Validate before calling
Object v = execution.getVariable("childResult");
if (!(v instanceof JsonNode) && !(v instanceof String && looksLikeJson((String) v))) {
throw new IllegalStateException("Variable must be JSON for aggregation");
} Type guard
boolean isJsonVariable(Object v) {
return v instanceof com.fasterxml.jackson.databind.JsonNode;
} Try / catch
try {
aggregated = aggregator.aggregateSingleVariable(ctx, varInstances);
} catch (FlowableException e) {
logger.error("Non-JSON variable in aggregation: " + e.getMessage(), e);
} Prevention
- Set variables intended for aggregation via JsonUtil helpers
- Keep the engine's JsonMapper configuration consistent
- Restrict aggregation to a known set of JSON-typed variables
When it happens
Trigger: Overview aggregation (e.g. root-process overview variables created by JsonChildProcessVariableAggregator-style flows) encountering a child-process variable whose value is a plain object (String, POJO, byte[]) rather than a JSON node.
Common situations: Process variables set via Java delegates to non-JSON types while parallel multi-instance child processes aggregate them into a parent overview variable; mixing serializedValueTypes so some variables come back as non-JSON.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Cannot aggregate variable
- Cannot aggregate overview variable
- Cannot aggregate variable
- Error converting request body to RestVariable instance
- Failed to read text value
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/4a0f86bc0a12d766.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/delegate/JsonVariableAggregator.java:160
case LocalDateType.TYPE_NAME:
case LocalDateTimeType.TYPE_NAME:
case JodaDateType.TYPE_NAME:
case JodaDateTimeType.TYPE_NAME:
case UUIDType.TYPE_NAME:
// For all these types it is OK to use toString as their string representation is what we want to have
objectNode.put(targetVarName, varInstance.getValue().toString());
break;
case ByteArrayType.TYPE_NAME:
objectNode.put(targetVarName, (byte[]) varInstance.getValue());
break;
default:
if (VariableAggregatorContext.OVERVIEW.equals(context.getState())) {
// We can only use the aggregated variable if we are in an overview state
Object value = varInstance.getValue();
if (jsonMapper.isJsonNode(value)) {
objectNode.set(targetVarName, JsonUtil.asFlowableJsonNode(value));
} else {
throw new FlowableException("Cannot aggregate overview variable: " + varInstance);
}
} else {
throw new FlowableException("Cannot aggregate variable: " + varInstance);
}
}
}
}
}
return objectNode.getImplementationValue();
}
@Override
public Object aggregateMultiVariables(DelegateExecution execution, List<? extends VariableInstance> instances, VariableAggregatorContext context) {
VariableJsonMapper objectMapper = processEngineConfiguration.getVariableJsonMapper();
FlowableArrayNode arrayNode = objectMapper.createArrayNode();
for (VariableInstance instance : instances) {View on GitHub (pinned to d6d39ce1c6)