flowable/flowable-engine · error · FlowableException
Cannot aggregate variable
Error message
Cannot aggregate variable: ${varInstance} What it means
Same aggregation path as the overview error but thrown when aggregation is NOT in OVERVIEW state and the variable value is not a JSON node. The aggregator only supports JSON-typed values in this branch of aggregateSingleVariable.
Solutions
- Store the aggregated variables as JSON nodes rather than plain Java types
- Verify which JsonMapper is configured and that it recognizes your variable values as JSON
- Filter variables before aggregation so only JSON variables reach the aggregator
- Wrap primitive values into a JSON object structure before setting them as variables
Example fix
// before
execution.setVariable("status", "DONE");
// after
execution.setVariable("status", JsonUtil.createChildObjectNode(null, "status", "DONE").get("status")); Defensive patterns
Strategy: type-guard
Validate before calling
for (VariableInstance vi : varInstances) {
if (!jsonMapper.isJsonNode(vi.getValue())) {
throw new IllegalStateException("Variable " + vi.getName() + " is not JSON");
}
} Type guard
boolean isJsonVariable(VariableInstance vi, FlowableJsonMapper m) {
return m.isJsonNode(vi.getValue());
} Try / catch
try {
result = aggregator.aggregateSingleVariable(ctx, varInstances);
} catch (FlowableException e) {
logger.warn("Skipping non-JSON aggregation input: " + e.getMessage());
} Prevention
- Store child-process result variables as JSON nodes only
- Avoid mixing primitive and JSON variable types under aggregation target names
- Test aggregation with all delegate variable types
When it happens
Trigger: Non-overview aggregation state receiving a variable instance whose value fails jsonMapper.isJsonNode(value) — e.g. a String, POJO or byte[] variable supplied to the JsonVariableAggregator.
Common situations: Child-process variables of simple types (String, Integer) collected by the JSON aggregator during parallel process-instance migrations or aggregation delegates.
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 overview 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/a23cff1e6a7b425b.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/delegate/JsonVariableAggregator.java:163
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) {
arrayNode.add(JsonUtil.asFlowableJsonNode(instance.getValue()));
}
View on GitHub (pinned to d6d39ce1c6)