Use a multi-instance activity (BPMN "loop / multi-instance" on an activity or sub-process): the engine creates one instance of the activity per element of a list, in parallel or sequentially, and continues when the completion condition is met. Setup in Process Designer (activity > Properties > Implementation > Multi-instance):
- Loop type: multi-instance; ordering: parallel (all at once) or sequential.
- Number of instances: an expression - the list length: tw.local.order.lines.listLength.
- Data: the multi-instance settings expose the current index as a system variable (shown in the property panel; tw.system.step.counter on recent releases); map tw.local.order.lines[<index>] as the input of the task and map its output back into the same element.
- Completion condition (optional): stop early, e.g. tw.local.rejections > 0 to cancel the remaining checks when one line is rejected.
BPD "Order review"
[Prepare lines] -> ⟦ Review line ⟧ (user task, multi-instance, parallel, count = tw.local.order.lines.listLength) -> [Consolidate] -> …
// "Review line" input mapping: line <- tw.local.order.lines[tw.system.step.counter]
// "Review line" output mapping: tw.local.order.lines[tw.system.step.counter] <- line (each instance writes its own element)
// completion condition (stop when any line is rejected): tw.local.rejected > 0 (a counter each instance increments in its output mapping script)
// [Consolidate] script after the multi-instance activity: gather the outcomes
var approved = 0, rejected = 0;
for (var i = 0; i < tw.local.order.lines.listLength; i++) { if (tw.local.order.lines[i].decision === "APPROVED") approved++; else rejected++; }
tw.local.order.status = rejected === 0 ? "APPROVED" : "PARTIALLY_REJECTED";Why not a loop with a gateway: a modelled loop runs sequentially and needs a counter variable; a multi-instance activity gives true parallel tasks with one model element, correct task naming (Review line 3 of 5 through the task subject expression), and a clean join. Rules: write each instance's output into its own list element (never into a shared scalar - last writer wins), keep the list stable while the tasks run (do not re-sort it), and use a sub-process as the multi-instance body when several steps per item are needed. The exact name of the index variable differs per release - the multi-instance property panel shows the available system variables.
References