{"record":{"id":"d8ce4b20c019cb52","repo":"flowable/flowable-engine","slug":"delegate-expression-aggregation-getimplementatio","errorCode":null,"errorMessage":"Delegate expression ${aggregation.getImplementation()} did not resolve to an implementation of ${PlanItemVariableAggregator.class}","messagePattern":"Delegate expression (.+?) did not resolve to an implementation of (.+?)","errorType":"exception","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/variable/CmmnAggregation.java","lineNumber":258,"sourceCode":"\n    public static Map<String, List<VariableInstance>> groupVariableInstancesByName(List<? extends VariableInstance> instances) {\n        return instances.stream().collect(Collectors.groupingBy(VariableInstance::getName));\n    }\n\n    public static PlanItemVariableAggregator resolveVariableAggregator(VariableAggregationDefinition aggregation, DelegatePlanItemInstance planItemInstance) {\n        CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration();\n        if (ImplementationType.IMPLEMENTATION_TYPE_CLASS.equalsIgnoreCase(aggregation.getImplementationType())) {\n            return cmmnEngineConfiguration.getClassDelegateFactory().create(aggregation.getImplementation(), null);\n        } else if (ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION.equalsIgnoreCase(aggregation.getImplementationType())) {\n            Object delegate = DelegateExpressionUtil.resolveDelegateExpression(\n                    cmmnEngineConfiguration.getExpressionManager().createExpression(aggregation.getImplementation()),\n                    planItemInstance, null);\n\n            if (delegate instanceof PlanItemVariableAggregator) {\n                return (PlanItemVariableAggregator) delegate;\n            }\n\n            throw new FlowableIllegalArgumentException(\"Delegate expression \" + aggregation.getImplementation() + \" did not resolve to an implementation of \" + PlanItemVariableAggregator.class);\n        } else {\n            return cmmnEngineConfiguration.getVariableAggregator();\n        }\n    }\n\n    public static void sortVariablesByCounter(List<VariableInstance> variableInstances, List<VariableInstance> counterVariableInstances) {\n        if (counterVariableInstances == null || counterVariableInstances.isEmpty()) {\n            return;\n        }\n        Map<String, Integer> sortOrder = new HashMap<>();\n        for (VariableInstance counterVariable : counterVariableInstances) {\n            Object value = counterVariable.getValue();\n            String[] values = value.toString().split(COUNTER_VAR_VALUE_SEPARATOR);\n            String variableInstanceId = values[0];\n            int order = Integer.parseInt(values[1]);\n            sortOrder.put(variableInstanceId, order);\n        }\n","sourceCodeStart":240,"sourceCodeEnd":276,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/variable/CmmnAggregation.java#L240-L276","documentation":"resolveVariableAggregator looks up a delegate bean via the aggregation's delegate expression and requires it to implement PlanItemVariableAggregator. If the expression resolves to an object of the wrong type (or non-null but incompatible), Flowable throws this FlowableIllegalArgumentException because the CMMN engine cannot aggregate plan item variables with the given delegate.","triggerScenarios":"A plan item's childRepetitionRule/variable aggregation declares a delegate expression (e.g. ${aggregation.getImplementation()}) that resolves to a bean not implementing PlanItemVariableAggregator; typo'd bean returning wrong type; custom aggregator class not implementing the interface.","commonSituations":"Copying a delegate class used elsewhere (e.g. a ValueProvider) into an aggregation role; upgrading Flowable where the aggregator interface changed; Spring bean wiring mistakes where the expression resolves to the factory or wrapper instead of the aggregator.","solutions":["Make the bean referenced by the delegate expression implement org.flowable.cmmn.engine.impl.variable.PlanItemVariableAggregator","Verify the delegate expression points at the correct bean (print/log aggregation.getImplementation() and check the Spring context bean type)","If no custom aggregation is needed, remove the delegate expression so the engine default variableAggregator from CmmnEngineConfiguration is used","Rebuild/redeploy after fixing so the case definition picks up the corrected class"],"exampleFix":"// before\npublic class MyAggregator { public Object aggregate(...) {...} }\n// after\npublic class MyAggregator implements PlanItemVariableAggregator {\n    public Object aggregate(PlanItemInstance planItemInstance, String variableName) {...}\n}","handlingStrategy":"validation","validationCode":"Object delegate = beanResolver.resolve(aggregation.getImplementation());\nif (!(delegate instanceof PlanItemVariableAggregator)) {\n    throw new IllegalStateException(aggregation.getImplementation() + \" must implement PlanItemVariableAggregator\");\n}","typeGuard":"boolean isAggregator(Object o) { return o instanceof PlanItemVariableAggregator; }","tryCatchPattern":"try {\n    aggregator = CmmnAggregation.resolveVariableAggregator(...);\n} catch (FlowableIllegalArgumentException e) {\n    logger.error(\"Aggregation delegate misconfigured: \" + e.getMessage());\n    throw e;\n}","preventionTips":["Have custom aggregators implement PlanItemVariableAggregator and add a unit test asserting the bean type","Keep delegate expressions pointing at aggregator beans only","Prefer omitting the delegate to use the engine default aggregator"],"tags":["cmmn","delegate-expression","type-mismatch","config"],"backgroundTag":"invalid-argument-value","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}