Gateway Troubleshooting
Common issues, error messages, debugging tips, and solutions for working with gateways in the BankLingo Process Engine.
Quick Diagnostic Checklist
Before diving into specific issues, run through this checklist:
- Check execution logs for gateway evaluation messages
- Verify all required BPMN elements are present (gateway, flows, tasks)
- Confirm variable values before gateway evaluation
- Ensure flow IDs/names match exactly in conditions
- Verify split and join gateways have matching path counts
- Check for XML syntax errors (escaped characters)
Table of Contents
- Exclusive Gateway Issues
- Parallel Gateway Issues
- Inclusive Gateway Issues
- Common Issues Across All Gateways
- Debugging Tips
- Log Interpretation
Exclusive Gateway Issues
Issue: Gateway always takes default flow
Symptoms: Process always goes to default path, even when other conditions should match.
Common Causes:
Cause 1: Condition script error
// ❌ Wrong - typo in variable name
return loanAmmount > 50000 ? 'Flow_High' : 'Flow_Low';
// ✅ Correct
return loanAmount > 50000 ? 'Flow_High' : 'Flow_Low';
Solution: Check logs for script evaluation errors:
[GATEWAY] ✗ ERROR: Script evaluation failed
[GATEWAY] Error: loanAmmount is not defined
[GATEWAY] ⚠ Falling back to default flow
Cause 2: Flow name mismatch
<!-- ❌ Wrong - script returns 'HighValue' but flow id is 'Flow_HighValue' -->
<custom:property name="Condition" value="return 'HighValue';" />
<bpmn:sequenceFlow id="Flow_HighValue" name="High Value" ... />
<!-- ✅ Correct - match exact ID or name -->
<custom:property name="Condition" value="return 'Flow_HighValue';" />
Check logs:
[GATEWAY] ✗ WARNING: Condition returned 'HighValue' but no matching flow found
[GATEWAY] Available flow IDs: Flow_HighValue, Flow_Standard
[GATEWAY] Available flow names: 'High Value', 'Standard'
[GATEWAY] ⚠ Falling back to default flow: Flow_Standard
Cause 3: Wrong condition expression syntax (flow-level)
<!-- ❌ Wrong - missing XML entities -->
<bpmn:conditionExpression>
amount > 50000 && creditScore >= 700
</bpmn:conditionExpression>
<!-- ✅ Correct - use XML entities -->
<bpmn:conditionExpression>
amount > 50000 && creditScore >= 700
</bpmn:conditionExpression>
Cause 4: Variable not set or undefined
// ❌ Wrong - accessing undefined variable
return customerType === 'PREMIUM' ? 'Flow_Premium' : 'Flow_Standard';
// If customerType is undefined, comparison fails
// ✅ Better - check existence first
if (customerType && customerType === 'PREMIUM') {
return 'Flow_Premium';
}
return 'Flow_Standard';
Issue: Process throws error at gateway
Symptoms: Process execution fails with error message.
Cause 1: No default flow and no matching condition
<!-- ❌ Wrong - no default, condition can fail to match -->
<bpmn:exclusiveGateway id="Gateway_1">
<bpmn:outgoing>Flow_A</bpmn:outgoing>
<bpmn:outgoing>Flow_B</bpmn:outgoing>
</bpmn:exclusiveGateway>
<bpmn:sequenceFlow id="Flow_A">
<bpmn:conditionExpression>status === 'ACTIVE'</bpmn:conditionExpression>
</bpmn:sequenceFlow>
<bpmn:sequenceFlow id="Flow_B">
<bpmn:conditionExpression>status === 'PENDING'</bpmn:conditionExpression>
</bpmn:sequenceFlow>
<!-- What if status === 'CLOSED'? No match, no default → ERROR -->
<!-- ✅ Correct - always have default -->
<bpmn:exclusiveGateway id="Gateway_1" default="Flow_B">
Cause 2: Gateway has no outgoing flows
<!-- ❌ Wrong - gateway leads nowhere -->
<bpmn:exclusiveGateway id="Gateway_1">
<bpmn:incoming>Flow_In</bpmn:incoming>
<!-- Missing: <bpmn:outgoing> -->
</bpmn:exclusiveGateway>
<!-- ✅ Correct - at least one outgoing flow -->
<bpmn:exclusiveGateway id="Gateway_1">
<bpmn:incoming>Flow_In</bpmn:incoming>
<bpmn:outgoing>Flow_Out</bpmn:outgoing>
</bpmn:exclusiveGateway>
Error Log:
[GATEWAY] ✗ ERROR: Exclusive gateway 'Gateway_1' has no outgoing flows
[PROCESS] Process execution failed at element: Gateway_1
Issue: Wrong path is taken
Symptoms: Process goes down unexpected path.
Debugging Steps:
- Check variable values before gateway:
[GATEWAY] Evaluating exclusive gateway: Gateway_Amount
[GATEWAY] Process variables at evaluation:
[GATEWAY] loanAmount = 75000
[GATEWAY] creditScore = 720
[GATEWAY] customerType = "INDIVIDUAL"
- Check condition evaluation:
[GATEWAY] Executing gateway-level condition script
[GATEWAY] ✓ Condition script returned: 'Flow_Senior'
- Verify condition logic:
// Is your logic correct?
if (loanAmount > 50000) {
return 'Flow_Senior'; // 75000 > 50000 → true → returns 'Flow_Senior'
} else {
return 'Flow_Standard';
}
Parallel Gateway Issues
Issue: Process hangs at join gateway
Symptoms: Join gateway shows ⏳ WAITING indefinitely in logs.
Cause 1: One parallel path hit an error
[TOKEN abc123] Processing Task_A...
[TOKEN abc123] ✓ Task completed successfully
[TOKEN def456] Processing Task_B...
[TOKEN def456] ✗ ERROR: Service call failed - Connection timeout
[TOKEN def456] Token execution halted
[PARALLEL GATEWAY] Token abc123 arrived at join
[PARALLEL GATEWAY] Expected tokens: 2
[PARALLEL GATEWAY] Arrived so far: 1/2
[PARALLEL GATEWAY] ⏳ WAITING - Not all paths completed
← STUCK HERE - Token def456 will never arrive
Solution: Fix the failing task. Check logs for errors in parallel paths.
Cause 2: One path has uncompleted UserTask
[TOKEN abc123] Task_A (ServiceTask) completed
[TOKEN def456] Task_B (UserTask) - Assigned to: ReviewerGroup
[TOKEN def456] ⏸ Waiting for user to complete task...
[PARALLEL GATEWAY] Waiting at join: 1/2 paths completed
← Waiting for user to complete Task_B
Solution: Complete the user task. Check if task is assigned correctly and user has access.
Cause 3: Split/Join path count mismatch
<!-- ❌ Wrong - split creates 3 paths, join expects only 2 -->
<bpmn:parallelGateway id="Gateway_Split">
<bpmn:outgoing>Flow_A</bpmn:outgoing>
<bpmn:outgoing>Flow_B</bpmn:outgoing>
<bpmn:outgoing>Flow_C</bpmn:outgoing> ← Creates 3 tokens
</bpmn:parallelGateway>
<!-- ... tasks execute ... -->
<bpmn:parallelGateway id="Gateway_Join">
<bpmn:incoming>Flow_FromA</bpmn:incoming>
<bpmn:incoming>Flow_FromB</bpmn:incoming> ← Only expects 2
<!-- Missing: Flow_FromC -->
</bpmn:parallelGateway>
Error Log:
[PARALLEL GATEWAY] Split created 3 tokens
[PARALLEL GATEWAY] Join expects 2 incoming flows
[PARALLEL GATEWAY] ⚠ WARNING: Token count mismatch!
Solution: Ensure split and join have the same number of paths:
<!-- ✅ Correct - both have 3 paths -->
<bpmn:parallelGateway id="Gateway_Split">
<bpmn:outgoing>Flow_A</bpmn:outgoing>
<bpmn:outgoing>Flow_B</bpmn:outgoing>
<bpmn:outgoing>Flow_C</bpmn:outgoing>
</bpmn:parallelGateway>
<bpmn:parallelGateway id="Gateway_Join">
<bpmn:incoming>Flow_FromA</bpmn:incoming>
<bpmn:incoming>Flow_FromB</bpmn:incoming>
<bpmn:incoming>Flow_FromC</bpmn:incoming>
</bpmn:parallelGateway>
Issue: Only one path executes (not parallel)
Symptoms: Log shows only 1 token created instead of multiple.
[PARALLEL GATEWAY] Evaluating parallel gateway: Gateway_Split
[PARALLEL GATEWAY] Outgoing flows: 1 ← Should be 2+
[PARALLEL GATEWAY] Type: PASS-THROUGH (single outgoing)
Cause: Gateway only has one <outgoing> flow.
Solution:
<!-- ❌ Wrong - only one outgoing -->
<bpmn:parallelGateway id="Gateway_1">
<bpmn:outgoing>Flow_A</bpmn:outgoing>
</bpmn:parallelGateway>
<!-- ✅ Correct - multiple outgoing flows -->
<bpmn:parallelGateway id="Gateway_1">
<bpmn:outgoing>Flow_A</bpmn:outgoing>
<bpmn:outgoing>Flow_B</bpmn:outgoing>
<bpmn:outgoing>Flow_C</bpmn:outgoing>
</bpmn:parallelGateway>
Issue: Race conditions / unexpected variable values
Symptoms: Variables have unexpected values after parallel execution.
Cause: Multiple tokens modifying the same variable simultaneously.
<!-- ❌ Problematic - both paths modify 'counter' -->
<bpmn:scriptTask id="Task_A">
<custom:property name="Script" value="counter = counter + 1;" />
</bpmn:scriptTask>
<bpmn:scriptTask id="Task_B">
<custom:property name="Script" value="counter = counter + 1;" />
</bpmn:scriptTask>
<!-- Result: counter might be 1 instead of 2 (race condition) -->
Solution: Use separate variables, combine after join.
<!-- ✅ Better - separate variables -->
<bpmn:scriptTask id="Task_A">
<custom:property name="Script" value="counterA = 1;" />
</bpmn:scriptTask>
<bpmn:scriptTask id="Task_B">
<custom:property name="Script" value="counterB = 1;" />
</bpmn:scriptTask>
<!-- After join: combine -->
<bpmn:scriptTask id="Task_Combine">
<custom:property name="Script" value="totalCounter = counterA + counterB;" />
</bpmn:scriptTask>
Inclusive Gateway Issues
Issue: No paths activate
Symptoms: Error - "No flows activated at inclusive gateway".
Cause: All conditions evaluated to false and no default flow.
<!-- ❌ Wrong - no default, all conditions can be false -->
<bpmn:inclusiveGateway id="Gateway_Notify">
<bpmn:outgoing>Flow_SMS</bpmn:outgoing>
<bpmn:outgoing>Flow_Push</bpmn:outgoing>
</bpmn:inclusiveGateway>
<bpmn:sequenceFlow id="Flow_SMS">
<bpmn:conditionExpression>hasPhone === true</bpmn:conditionExpression>
</bpmn:sequenceFlow>
<bpmn:sequenceFlow id="Flow_Push">
<bpmn:conditionExpression>hasApp === true</bpmn:conditionExpression>
</bpmn:sequenceFlow>
<!-- If both hasPhone and hasApp are false → NO PATHS ACTIVATE → ERROR -->
Solution: Add a default flow or unconditional flow.
<!-- ✅ Correct - add default -->
<bpmn:inclusiveGateway id="Gateway_Notify" default="Flow_Email">
<bpmn:outgoing>Flow_Email</bpmn:outgoing> ← No condition = always
<bpmn:outgoing>Flow_SMS</bpmn:outgoing>
<bpmn:outgoing>Flow_Push</bpmn:outgoing>
</bpmn:inclusiveGateway>
Issue: Join waits for wrong token count
Symptoms: Join shows ⏳ WAITING with unexpected numbers.
[INCLUSIVE GATEWAY] Activated 2 paths at split
[INCLUSIVE GATEWAY] Join waiting for: 3 tokens ← Mismatch!
This indicates a bug in the implementation. The join should only wait for tokens that were activated at the split.
Workaround: Ensure BPMN model is correct:
- Check split logs to see which paths were activated
- Verify join has incoming flows for all possible paths
- Report issue if join doesn't match split activation
Issue: Wrong paths activate
Symptoms: Unexpected tasks execute.
Debugging Steps:
- Check condition evaluation in logs:
[INCLUSIVE GATEWAY] Evaluating individual flow conditions:
[INCLUSIVE GATEWAY] Flow_Email: true (no condition)
[INCLUSIVE GATEWAY] ✓ Activated
[INCLUSIVE GATEWAY] Flow_SMS: false
[INCLUSIVE GATEWAY] ✗ Not activated
[INCLUSIVE GATEWAY] Flow_Push: true
[INCLUSIVE GATEWAY] ✓ Activated
- Verify variable values:
[INCLUSIVE GATEWAY] Variables at evaluation:
[INCLUSIVE GATEWAY] hasPhone = false ← Check if this is correct
[INCLUSIVE GATEWAY] hasApp = true
- Check condition logic:
<!-- Are your conditions correct? -->
<bpmn:conditionExpression>
hasPhone === true ← Should this be !== null instead?
</bpmn:conditionExpression>
Issue: Gateway-level condition returns invalid flow names
Symptoms: Warning in logs, falls back to default.
[INCLUSIVE GATEWAY] ✗ WARNING: Condition returned 'Flow_Sms' but no such flow exists
[INCLUSIVE GATEWAY] Available flows: Flow_SMS, Flow_Email, Flow_Push
Cause: Typo in flow name returned by script.
Solution:
// ❌ Wrong - typo
return 'Flow_Email,Flow_Sms'; // Should be 'Flow_SMS'
// ✅ Correct - exact match
return 'Flow_Email,Flow_SMS';
// ✅ Better - use constants
const FLOWS = {
EMAIL: 'Flow_Email',
SMS: 'Flow_SMS',
PUSH: 'Flow_Push'
};
return `${FLOWS.EMAIL},${FLOWS.SMS}`;
Common Issues Across All Gateways
Issue: Variable is undefined in gateway condition
Symptoms: Condition evaluation fails or behaves unexpectedly.
Cause: Variable not set before gateway is reached.
Solution: Set variables in a ScriptTask before the gateway.
<!-- Set variables first -->
<bpmn:scriptTask id="Task_PrepareVars" name="Prepare Variables">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="Script" value="
// Set defaults if undefined
loanAmount = loanAmount || 0;
creditScore = creditScore || 0;
customerType = customerType || 'STANDARD';
" />
</custom:properties>
</bpmn:extensionElements>
</bpmn:scriptTask>
<bpmn:sequenceFlow sourceRef="Task_PrepareVars" targetRef="Gateway_Check" />
<bpmn:exclusiveGateway id="Gateway_Check">
<!-- Now variables are guaranteed to exist -->
</bpmn:exclusiveGateway>
Issue: XML parsing error
Symptoms: Process won't load or parse, XML error.
Common Causes:
Cause 1: Unescaped special characters
<!-- ❌ Wrong - unescaped & and < -->
<bpmn:conditionExpression>
amount > 50000 && creditScore < 700
</bpmn:conditionExpression>
<!-- ✅ Correct - use XML entities -->
<bpmn:conditionExpression>
amount > 50000 && creditScore < 700
</bpmn:conditionExpression>
XML Entity Reference:
| Character | XML Entity |
|---|---|
& | & |
< | < |
> | > |
" | " |
' | ' |
Cause 2: Missing closing tags
<!-- ❌ Wrong - missing closing tag -->
<bpmn:exclusiveGateway id="Gateway_1">
<bpmn:incoming>Flow_In</bpmn:incoming>
<bpmn:outgoing>Flow_Out</bpmn:outgoing>
<!-- Missing: </bpmn:exclusiveGateway> -->
<!-- ✅ Correct -->
<bpmn:exclusiveGateway id="Gateway_1">
<bpmn:incoming>Flow_In</bpmn:incoming>
<bpmn:outgoing>Flow_Out</bpmn:outgoing>
</bpmn:exclusiveGateway>
Issue: Gateway is not reached
Symptoms: Logs show process stops before gateway.
Possible Causes:
- Previous task failed
[PROCESS] Processing Task_Validate...
[PROCESS] ✗ ERROR: Validation failed
[PROCESS] Process execution halted
← Gateway never reached
- Sequence flow has unmet condition
<!-- Flow between task and gateway has a condition -->
<bpmn:sequenceFlow sourceRef="Task_A" targetRef="Gateway_1">
<bpmn:conditionExpression>
proceedToGateway === true ← If false, flow not taken
</bpmn:conditionExpression>
</bpmn:sequenceFlow>
Solution: Remove condition from sequence flows (only gateways should have routing logic):
<!-- ✅ Correct - no condition on regular flow -->
<bpmn:sequenceFlow sourceRef="Task_A" targetRef="Gateway_1" />
Debugging Tips
Enable Detailed Logging
Check process execution logs for gateway-specific messages:
[GATEWAY] - Gateway evaluation messages
[PARALLEL GATEWAY] - Parallel gateway specific messages
[INCLUSIVE GATEWAY] - Inclusive gateway specific messages
[TOKEN xyz] - Token-specific execution messages
Step-by-Step Gateway Debugging
- Identify the gateway in logs:
[GATEWAY] Evaluating exclusive gateway: Gateway_Amount (Check Loan Amount)
- Check variables at that moment:
[GATEWAY] Process variables at evaluation:
[GATEWAY] loanAmount = 75000
[GATEWAY] creditScore = 720
- See condition evaluation:
[GATEWAY] Executing gateway-level condition script
[GATEWAY] ✓ Condition script returned: 'Flow_Senior'
- Verify flow selection:
[GATEWAY] ✓ DECISION: Taking flow 'Flow_Senior' → Task_SeniorApproval
- Check for warnings or errors:
[GATEWAY] ✗ WARNING: ...
[GATEWAY] ✗ ERROR: ...
Test Gateway Conditions in Isolation
Create a simple test process with just the gateway:
<bpmn:startEvent id="Start" />
<bpmn:scriptTask id="Task_SetVars" name="Set Test Variables">
<custom:property name="Script" value="
loanAmount = 75000;
creditScore = 720;
" />
</bpmn:scriptTask>
<bpmn:exclusiveGateway id="Gateway_Test">
<!-- Your gateway configuration -->
</bpmn:exclusiveGateway>
<bpmn:serviceTask id="Task_PathA" name="Path A" />
<bpmn:serviceTask id="Task_PathB" name="Path B" />
<bpmn:endEvent id="End" />
Use Process Variables Viewer
If your process engine has a variables viewer, check variable values at the moment the gateway is evaluated.
Log Interpretation
Exclusive Gateway Logs
Successful evaluation:
[GATEWAY] Evaluating exclusive gateway: Gateway_1
[GATEWAY] Available paths: 3
[GATEWAY] Executing gateway-level condition script
[GATEWAY] ✓ Condition script returned: 'Flow_A'
[GATEWAY] ✓ DECISION: Taking flow 'Flow_A' → Task_A
[GATEWAY] Moving to element: Task_A
Error - no match found:
[GATEWAY] ✗ WARNING: Condition returned 'Flow_X' but no matching flow found
[GATEWAY] Available flow IDs: Flow_A, Flow_B, Flow_C
[GATEWAY] ⚠ Falling back to default flow: Flow_A
Error - script failed:
[GATEWAY] ✗ ERROR: Script evaluation failed
[GATEWAY] Error: loanAmount is not defined
[GATEWAY] ⚠ Falling back to default flow
Parallel Gateway Logs
Split (successful):
[PARALLEL GATEWAY] Evaluating: Gateway_Split
[PARALLEL GATEWAY] Type: SPLIT/FORK
[PARALLEL GATEWAY] Outgoing flows: 3
[PARALLEL GATEWAY] Creating 3 parallel execution paths:
[PARALLEL GATEWAY] → Token abc...
[PARALLEL GATEWAY] → Token def...
[PARALLEL GATEWAY] → Token ghi...
[PARALLEL GATEWAY] ✓ Parallel split complete
Join (in progress):
[PARALLEL GATEWAY] Token abc arrived at join: Gateway_Join
[PARALLEL GATEWAY] Expected tokens: 3
[PARALLEL GATEWAY] Arrived so far: 1/3
[PARALLEL GATEWAY] ⏳ WAITING - Not all paths completed yet
Join (complete):
[PARALLEL GATEWAY] Token ghi arrived at join: Gateway_Join
[PARALLEL GATEWAY] Expected tokens: 3
[PARALLEL GATEWAY] Arrived so far: 3/3
[PARALLEL GATEWAY] ✓ ALL PATHS COMPLETED
[PARALLEL GATEWAY] Merging tokens and continuing...
Inclusive Gateway Logs
Split (successful):
[INCLUSIVE GATEWAY] Evaluating: Gateway_Notify
[INCLUSIVE GATEWAY] Evaluating individual flow conditions:
[INCLUSIVE GATEWAY] Flow_Email: true (no condition)
[INCLUSIVE GATEWAY] ✓ Activated
[INCLUSIVE GATEWAY] Flow_SMS: true
[INCLUSIVE GATEWAY] ✓ Activated
[INCLUSIVE GATEWAY] Flow_Push: false
[INCLUSIVE GATEWAY] ✗ Not activated
[INCLUSIVE GATEWAY] ✓ Activated 2 paths out of 3
[INCLUSIVE GATEWAY] Creating execution tokens...
Join (waiting):
[INCLUSIVE GATEWAY] Token abc arrived at join
[INCLUSIVE GATEWAY] Expected tokens from split: 2
[INCLUSIVE GATEWAY] Arrived so far: 1/2
[INCLUSIVE GATEWAY] ⏳ WAITING - 1/2 activated paths completed
Quick Solutions Reference
| Problem | Quick Fix |
|---|---|
| Always takes default | Check flow name matches, add default attribute |
| Process hangs at join | Check all parallel paths complete, verify token count |
| Wrong path taken | Check variable values, verify condition logic |
| No paths activate | Add default flow to Exclusive/Inclusive gateway |
| XML parse error | Escape special characters (&, <, >) |
| Variable undefined | Set variables in ScriptTask before gateway |
| Only one path executes | Add multiple <outgoing> tags to Parallel gateway |
| Race condition | Use separate variables in parallel paths |
Getting Help
If you're still stuck after trying these solutions:
- Collect gateway logs - Copy the relevant log section
- Note variable values - What were the values when gateway was evaluated?
- Share BPMN XML - The gateway and related flows
- Describe expected vs actual - What should happen vs what actually happens
- Check this documentation - Exclusive | Parallel | Inclusive
Summary
Most gateway issues fall into these categories:
- Configuration: Missing default flows, wrong flow names
- Logic: Incorrect conditions, variable issues
- Structure: Mismatched split/join counts, missing flows
- Syntax: XML escaping, missing tags
Always check logs first - they show exactly what the gateway is doing and why!