Our Architect flow uses a common module that retries invalid DTMF input by calling itself. After 3 retries, the platform throws a loop detection error and disconnects the caller.
We need 5 retries maximum. Is there a way to increase the loop detection threshold?
You cannot increase the threshold. The platform caps common module recursion at 5 levels.
Replace the recursive pattern with a Loop action and a counter variable:
Set retryCount = 0
Loop While retryCount < 5
Collect DTMF
If valid → Exit Loop
Else → retryCount = retryCount + 1
End Loop
If retryCount >= 5 → Transfer to agent
We built a reusable ‘SafeRetry’ utility module used across 30+ flows.
The module accepts maxRetries and currentAttempt as inputs. The PARENT flow manages the counter, completely avoiding recursion. Every new flow imports this module instead of building its own retry logic.
From a containment perspective, the number of retries directly affects self-service success.
Our data: 2 retries = 48% containment. 3 retries = 55%. 5 retries = 61%. But CSAT drops significantly after 3 retries. The sweet spot is 3 retries with a friendly ‘Let me connect you to an agent’ on the 4th attempt.
In CIC, custom handlers had no recursion limit. You could write infinite loops.
GC’s 5-level limit is actually a safety feature for a multi-tenant cloud platform. One customer’s infinite loop shouldn’t consume shared resources. The constraint is reasonable, but the error message should be more descriptive.
Under healthcare regulations, disconnecting a patient caller due to loop detection is a reportable event.
The flow MUST provide a path to a live agent after maximum retries, never a disconnect. We audit every flow for disconnect blocks that could be reached via retry exhaustion.
We A/B tested different retry UX patterns.
| Pattern |
Containment |
CSAT |
Disconnect Rate |
| Same prompt repeated |
48% |
3.6 |
4% |
| Progressively simpler prompts |
55% |
4.0 |
1% |
| Offer agent on 3rd retry |
52% |
4.2 |
0% |
Progressive simplification works best - shorten the menu on each retry.
The loop detection error in the execution log just says ‘FLOW_LOOP_DETECTED’ with no module name.
With 12 nested common modules, finding which one triggered the detection takes hours of manual tracing. We need better error diagnostics.
# Trace common module call depth
def analyze_flow_dependencies(flow_id, depth=0):
flow = architect_api.get_flow(flow_id)
for ref in flow.referenced_modules:
indent = ' ' * depth
print(f'{indent}→ {ref.name} (depth {depth})')
if depth > 4:
print(f'{indent} ⚠️ RISK: Approaching loop detection limit!')
analyze_flow_dependencies(ref.id, depth + 1)
Run this before publishing to catch potential loop issues.
Does loop detection apply across different flow types?
If an inbound call flow calls a common module, which calls an in-queue flow via transfer, which calls another common module - does the loop counter span all flow types or reset per flow?
Loop detection resets when the flow type changes.
The recursion counter tracks common module depth within a single flow execution. A transfer to a new flow (inbound, in-queue, or outbound) resets the counter. So an inbound flow with 4 levels of modules can transfer to an in-queue flow with another 4 levels without triggering detection.