flowable/flowable-engine · error · FlowableException
Cannot aggregate overview variable: ${varInstance}
Error message
Cannot aggregate overview variable: ${varInstance} What it means
JsonPlanItemVariableAggregator.aggregateSingleVariable builds an overview aggregate variable from the values of repeated plan items. In the OVERVIEW context state, each collected instance's value must be a JSON node; when varInstance's value is not a JSON node, this FlowableException is thrown because the value cannot be placed into the overview JSON object.
Source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/delegate/JsonPlanItemVariableAggregator.java:159
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 (PlanItemVariableAggregatorContext.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(DelegatePlanItemInstance planItemInstance, List<? extends VariableInstance> instances,
PlanItemVariableAggregatorContext context) {
VariableJsonMapper objectMapper = cmmnEngineConfiguration.getVariableJsonMapper();
FlowableArrayNode arrayNode = objectMapper.createArrayNode();View on GitHub (pinned to d6d39ce1c6)
Solutions
- Ensure every variable aggregated in overview state stores a JSON node value (use JsonUtil/create Flowable JSON values when setting the variable).
- Convert the value to JSON before storing it, e.g. via jsonMapper/JsonUtil.asFlowableJsonNode in the producing delegate.
- Adjust the aggregation configuration to target variables that are guaranteed JSON-typed.
- Add a wrapper delegate that normalizes non-JSON values into JSON nodes before aggregation.
Example fix
// before
planItemInstance.setVariable("result", "someString");
// after
planItemInstance.setVariable("result", JsonUtil.createObjectNode().put("value", "someString")); Defensive patterns
Strategy: validation
Validate before calling
Object value = varInstance.getValue();
if (!(value instanceof com.fasterxml.jackson.databind.JsonNode)) {
value = JsonUtil.asFlowableJsonNode(value); // or reject before aggregation
} Type guard
boolean isJsonValued(VariableInstance v) {
return v != null && (v.getValue() instanceof com.fasterxml.jackson.databind.JsonNode);
} Try / catch
try {
Object result = aggregator.aggregateSingleVariable(planItemInstance, context);
} catch (org.flowable.common.engine.api.FlowableException e) {
if (e.getMessage().startsWith("Cannot aggregate overview variable")) { log.error("Non-JSON value in overview aggregation: {}", e.getMessage()); }
throw e;
} Prevention
- Only write JSON node values into variables included in repetition aggregation.
- Normalize values with JsonUtil at variable-creation time, not at aggregation time.
- Document which variables your aggregation config consumes and enforce their type.
When it happens
Trigger: A plan item repetition defines aggregation into a variable in OVERVIEW state (e.g. stage/milestone overview with completion/available counts), and one of the aggregated instance variables holds a non-JSON value (String, number, POJO, null serialized type) instead of a Flowable-JSON node.
Common situations: Custom variable writers storing plain Java objects or primitives into the aggregated variable; a previous state stored a simple type that later gets re-aggregated in overview; mixing custom delegates that set non-JSON values.
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
- Cannot aggregate variable: ${varInstance}
- ${className} does not implement the ${CmmnTriggerableActivit
- ${className} does not implement the ${CmmnActivityBehavior.c
- ${delegateInstance.getClass().getName()} doesn't implement $
- ${delegateInstance.getClass().getName()} doesn't implement $
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/70c18cef629d102b.
Report an issue: GitHub.