A BPMN 2.0 claim model splits with an exclusive gateway into fast-track and full assessment, then rejoins them with a parallel gateway; why does every claim hang there?
answer
- count tokens per branch
- a join waits for every input
- alternatives never all arrive
- the reverse mismatch duplicates
basics
~20 sIn BPMN 2.0 the exclusive split puts a token on only one branch, but a parallel join waits for a token on every incoming flow. The missing token never comes, so the instance deadlocks. Alternatives must merge with an exclusive gateway.
solid answer
~40 sCount the tokens. The exclusive split "Below fast-track threshold?" sends the claim's single token down **one** branch, fast-track or full assessment. A **parallel join** is activated only when **every** incoming flow holds a token, so it waits for a token from the branch that was never taken: the instance **deadlocks** there, with nothing to throw an error. The fix is to merge alternatives with an **exclusive** gateway, which passes each token straight through. The **reverse mismatch** fails differently: a parallel split into "Medical report" and "Police report" joined by an **exclusive** merge lets **both** tokens through, so "Assess liability" runs **twice**. The rule behind both: close a split with a join of the same semantics, or reason the token count through explicitly.
go deeper
Recall that an exclusive split takes one branch and a parallel join waits for all of them, so the pair cannot work together.
Walk the tokens through all four split and join combinations and name the result of each: correct, deadlock or duplication.
Diagnose stuck or doubled instances from the model by counting tokens, fix the gateway types, and push for structured split-join blocks in reviews.
Introduce model-checking or review gates for split and join pairs so deadlocks are caught before deployment rather than found as stuck claims.
## Diagnosing with the token game BPMN 2.0 (OMG formal/13-12-09) defines behaviour with **tokens**: every gateway consumes and produces tokens according to its type. A deadlock or a duplicated step is almost always found by counting tokens on each sequence flow. The model in question routes an insurance claim: 1. "Register claim", then an **exclusive split**: below the fast-track threshold, go to "Fast-track settlement"; otherwise go to "Full assessment". 2. Both branches then enter a **parallel gateway** used as a join, followed by "Notify claimant". ## Why it hangs - The exclusive split produces **one** token, on **one** branch, by definition. - The parallel gateway is activated only when there is **at least one token on each incoming sequence flow**; it then consumes one from each. - The branch that was not taken will never carry a token for this instance. So the token that did arrive waits at the join for ever. No gateway throws an exception for this: the parallel gateway "cannot throw any exception" in the specification, it simply is never activated. The instance never completes, because a process completes only when no tokens remain. ## The reverse mismatch duplicates work Now take the report step: a **parallel split** starts "Obtain medical report" and "Obtain police report", and the branches meet at an **exclusive** gateway before "Assess liability". - The parallel split produces **two** tokens. - A converging exclusive gateway routes **each** arriving token to its output **without synchronisation**. - So "Assess liability" runs once when the first report arrives, with half the information, and **again** when the second arrives. Everything downstream is doubled: two decisions, two letters, possibly two payments. ## The four combinations | Split | Join | Result | |---|---|---| | Exclusive | Exclusive | correct: one token in, one token out | | Parallel | Parallel | correct: all branches synchronised | | Exclusive | Parallel | **deadlock**: the join waits for branches never started | | Parallel | Exclusive | **duplication**: the step after the merge runs once per branch | An inclusive split closed by an inclusive join is also correct, since the join waits only for the branches that were started. Closing an inclusive split with a parallel join deadlocks whenever not all branches were taken; closing it with an exclusive merge duplicates whenever more than one was. ## Tracing the corrected model With the join replaced by an exclusive merge, trace one claim below the threshold: 1. "Register claim" completes; one token reaches the exclusive split. 2. The first true condition, "below the fast-track threshold", sends the token to "Fast-track settlement". 3. The token reaches the exclusive merge and passes straight through; no other input is consulted. 4. "Notify claimant" runs once, the token reaches an end event, and the instance completes. For the report step, replace the exclusive merge with a parallel join and trace again: two tokens leave the parallel split, the first to arrive waits at the join, the second activates it, one token continues, and "Assess liability" runs once with both reports. Tracing the corrected model this way, once per possible path, is the fastest check that the fix is complete. ## Fixing and preventing it - **Merge alternatives with an exclusive gateway**, or let them enter the next activity directly, which behaves as an exclusive merge. - **Join parallel branches with a parallel gateway**, so the next step runs once with all results. - Prefer **structured** models, where every split has a matching join of the same type enclosing a single-entry, single-exit block. Structured models are much easier to verify. - When branches genuinely come from different kinds of splits, reason about each case separately: what tokens exist when the first one reaches the join, and can the others still arrive? ## Mistakes in the diagnosis itself - Blaming the executing engine. The behaviour follows directly from the specification's gateway semantics, so the model is what must change. - "Fixing" the deadlock by adding a timer to the join. Gateways have no timeout, and a timer elsewhere hides the modelling error rather than removing it. - Replacing the join with an inclusive gateway without checking the upstream structure. It works here, but its synchronisation depends on the whole model and is easy to get wrong in loops.
- In BPMN 2.0, why does no error appear when a parallel join waits for a token that will never arrive?The parallel gateway cannot throw an exception; it is simply never activated. The token stays on its incoming flow and the instance cannot complete, because completion requires that no token remains. The fault shows up as instances that are stuck, not failed.
- In BPMN 2.0, why does a parallel split followed by an exclusive merge run the next task twice?The parallel split puts one token on each branch. A converging exclusive gateway passes every arriving token through without synchronisation, so both tokens reach the next task, one after the other, and it runs once per token.
saying these in an interview costs you the question
- A parallel join continues once any branch arrives.
- An exclusive merge waits for all incoming branches before passing on.
- The engine should detect that the other branch was never taken and skip waiting.
- A deadlocked gateway throws an exception that ends the instance.
- Adding a timer to the join is the right fix for the hang.