docs/tools/loop-detection.md
OpenClaw can keep agents from getting stuck in repeated tool-call patterns. The guard is disabled by default.
Enable it only where needed, because it can block legitimate repeated calls with strict settings.
Global defaults:
{
tools: {
loopDetection: {
enabled: false,
historySize: 30,
warningThreshold: 10,
criticalThreshold: 20,
globalCircuitBreakerThreshold: 30,
detectors: {
genericRepeat: true,
knownPollNoProgress: true,
pingPong: true,
},
},
},
}
Per-agent override (optional):
{
agents: {
list: [
{
id: "safe-runner",
tools: {
loopDetection: {
enabled: true,
warningThreshold: 8,
criticalThreshold: 16,
},
},
},
],
},
}
enabled: Master switch. false means no loop detection is performed.historySize: number of recent tool calls kept for analysis.warningThreshold: threshold before classifying a pattern as warning-only.criticalThreshold: threshold for blocking repetitive loop patterns.globalCircuitBreakerThreshold: global no-progress breaker threshold.detectors.genericRepeat: detects repeated same-tool + same-params patterns.detectors.knownPollNoProgress: detects known polling-like patterns with no state change.detectors.pingPong: detects alternating ping-pong patterns.For exec, no-progress checks compare stable command outcomes and ignore volatile runtime metadata such as duration, PID, session ID, and working directory.
When a run id is available, recent tool-call history is evaluated only within that run so scheduled heartbeat cycles and fresh runs do not inherit stale loop counts from earlier runs.
enabled: true, defaults unchanged. Flagship models rarely need loop detection and can leave it disabled.warningThreshold < criticalThreshold < globalCircuitBreakerThreshold.warningThreshold and/or criticalThresholdglobalCircuitBreakerThresholdhistorySize for less strict historical contextWhen the runner completes an auto-compaction-retry (after a context-overflow), it arms a short-window guard that watches the next few tool calls. If the agent emits the same (toolName, args, result) triple multiple times within that window, the guard concludes that compaction did not break the loop and aborts the run with a compaction_loop_persisted error.
This is a separate code path from the global tools.loopDetection detectors. It is independently configurable:
{
tools: {
loopDetection: {
enabled: true, // existing master switch; set false to disable loop guards
postCompactionGuard: {
windowSize: 3, // default: 3
},
},
},
}
windowSize: number of post-compaction tool calls during which the guard stays armed and the count of identical (tool, args, result) triples that triggers an abort.The guard never aborts when results are changing, only when results are byte-identical across the window. It is intentionally narrow: it fires only in the immediate aftermath of a compaction-retry.
When a loop is detected, OpenClaw reports a loop event and blocks or dampens the next tool-cycle depending on severity. This protects users from runaway token spend and lockups while preserving normal tool access.
tools.loopDetection is merged with agent-level overrides.