{"record":{"id":"1f86d05e1fc30ddd","repo":"flowable/flowable-engine","slug":"could-not-evaluate-collection-for-repetition-rule","errorCode":null,"errorMessage":"Could not evaluate collection for repetition rule on plan item with id '${planItemInstanceEntity.getId()}', collection variable name '${repetitionRule.getCollectionVariableName()}' evaluated to '${collection}', but needs to be a collection, an iterable or an ArrayNode (JSON).","messagePattern":"Could not evaluate collection for repetition rule on plan item with id '(.+?)', collection variable name '(.+?)' evaluated to '(.+?)', but needs to be a collection, an iterable or an ArrayNode \\(JSON\\)\\.","errorType":"exception","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/util/ExpressionUtil.java","lineNumber":168,"sourceCode":"            return null;\n        }\n\n        String collectionExpression = repetitionRule.getCollectionVariableName();\n\n        if (!(collectionExpression.startsWith(\"${\") || collectionExpression.startsWith(\"#{\"))) {\n            collectionExpression = \"${vars:getOrDefault('\" + collectionExpression + \"', null)}\";\n        }\n\n        Object collection = evaluateExpression(commandContext, planItemInstanceEntity, collectionExpression);\n        if (collection == null) {\n            return null;\n        }\n\n        if (collection instanceof Iterable) {\n            return (Iterable<Object>) collection;\n        }\n\n        throw new FlowableIllegalArgumentException(\"Could not evaluate collection for repetition rule on plan item with id '\" + planItemInstanceEntity.getId() +\n            \"', collection variable name '\" + repetitionRule.getCollectionVariableName() + \"' evaluated to '\" + collection +\n            \"', but needs to be a collection, an iterable or an ArrayNode (JSON).\");\n    }\n\n    /**\n     * Returns true, if: the given plan item instance has a repetition rule at all and if so, if it has a condition witch is satisfied and all in combination\n     * with the optional max instance count attribute. If the repetition rule evaluates to true, this normally means that there should be an additional\n     * instance of the plan item created.\n     *\n     * @param commandContext the command context in which this evaluation is taking place\n     * @param planItemInstanceEntity the plan item instance entity to test for a repetition rule to evaluate to true\n     * @param planItemInstanceContainer the container (usually the parent stage of the plan item instance) to get access to child plan items\n     * @return true, if there is a repetition rule of the plan item instance currently evaluating to true with all of its conditions and attributes\n     */\n    public static boolean evaluateRepetitionRule(CommandContext commandContext, PlanItemInstanceEntity planItemInstanceEntity,\n            PlanItemInstanceContainer planItemInstanceContainer) {\n        \n        RepetitionRule repetitionRule = getRepetitionRule(planItemInstanceEntity);","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/util/ExpressionUtil.java#L150-L186","documentation":"ExpressionUtil.evaluateRepetitionCollectionVariableValue resolves the repetition rule's collection variable and accepts only Collection, Iterable, or JSON ArrayNode values. Any other type (String, Map handled elsewhere?, scalar, null beyond the earlier guard) causes this FlowableIllegalArgumentException, since multi-instance/repetition requires something iterable to create plan item instances from.","triggerScenarios":"A plan item has a repetition rule with a collectionVariableName whose variable resolves to a non-iterable value — e.g. a comma-separated String like 'a,b,c', a single object, or a number — when the engine evaluates the repetition rule at plan item creation.","commonSituations":"Storing CSV strings in a variable and pointing collectionVariableName at them; a variable overwritten by later logic from a List to a scalar; JSON returned as an ObjectNode rather than ArrayNode; type changes after a model refactor.","solutions":["Set the collection variable to a java.util.Collection/List, an Iterable, or a com.fasterxml.jackson.databind.node.ArrayNode","If the source data is a delimited String, split it first: Arrays.asList(csv.split(\",\")) and store that as the variable","Ensure the JSON payload is parsed as an ArrayNode (e.g. objectMapper.readTree returning an array) not a scalar/object","Add a check/log of the variable's type at runtime to catch upstream overwrites"],"exampleFix":"// before\nexecution.setVariable(\"items\", \"item1,item2\");\n// after\nexecution.setVariable(\"items\", Arrays.asList(\"item1\", \"item2\"));","handlingStrategy":"validation","validationCode":"Object collection = variableContainer.getVariable(repetitionRule.getCollectionVariableName());\nif (!(collection instanceof Collection) && !(collection instanceof Iterable) && !(collection instanceof ArrayNode)) {\n    throw new IllegalStateException(\"Repetition collection variable '\" + repetitionRule.getCollectionVariableName() + \"' must be Collection/Iterable/ArrayNode, got: \" + (collection == null ? \"null\" : collection.getClass()));\n}","typeGuard":"boolean isRepetitionCollection(Object v) { return v instanceof Iterable || v instanceof ArrayNode; }","tryCatchPattern":"try { evaluateRepetition(); } catch (FlowableIllegalArgumentException e) { if (e.getMessage().contains(\"repetition rule\")) { log.error(\"Collection variable '{}' has wrong type\", repetitionRule.getCollectionVariableName()); throw e; } throw e; }","preventionTips":["Store repetition collections as List/Set or JSON ArrayNode only","Split delimited strings into lists before assigning to collection variables","Watch for later overwrites that change the variable's type"],"tags":["cmmn","repetition","collection","type-mismatch","flowable"],"backgroundTag":"incompatible-source-type","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}