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

  1. Ensure every variable aggregated in overview state stores a JSON node value (use JsonUtil/create Flowable JSON values when setting the variable).
  2. Convert the value to JSON before storing it, e.g. via jsonMapper/JsonUtil.asFlowableJsonNode in the producing delegate.
  3. Adjust the aggregation configuration to target variables that are guaranteed JSON-typed.
  4. 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

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


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/70c18cef629d102b. Report an issue: GitHub.