This issue was drafted with help from an AI coding agent after reproducing the behavior locally and inspecting the relevant source paths. I reviewed the contents before posting. Marking it as agent-generated for clarity.
Prerequisites
Bug Description
Background subagents such as explore and librarian are being cancelled by the repetitive-tool circuit breaker during legitimate research/search bursts.
The detector appears to treat repeated use of the same tool name as an infinite loop even when the inputs differ materially, which is common for glob, grep, bash, and similar exploration tools.
Steps to Reproduce
- Run a task that asks
explore to search broadly across a codebase, or asks librarian to inspect an external repo/docs with many search/tool turns.
- Let the subagent perform a burst of repeated search calls with different queries/paths.
- Observe background-task cancellation.
Two concrete reproductions from my session:
[BACKGROUND TASK CANCELLED]
ID: bg_4ac25da9
Description: Find explorer kill logic
Error: Subagent repeatedly called glob 16/16 times in the recent tool-call window (80% threshold). This usually indicates an infinite loop. The task was automatically cancelled to prevent excessive token usage.
[BACKGROUND TASK CANCELLED]
ID: bg_390c502a
Description: Inspect upstream plugin changes
Error: Subagent repeatedly called bash 16/16 times in the recent tool-call window (80% threshold). This usually indicates an infinite loop. The task was automatically cancelled to prevent excessive token usage.
Expected Behavior
Search-heavy agents should be allowed to use the same tool many times in a row when the inputs differ and progress is still being made.
A real loop detector should still catch repeated identical or near-identical tool calls, but it should not kill healthy exploration solely because the tool name repeats.
Actual Behavior
The background circuit breaker cancels the subagent mid-task, which prevents explore / librarian from finishing legitimate investigations.
Doctor Output
oMoMoMoMo Doctor
⚠ 1 issue found:
1. Comment checker unavailable
Comment checker binary is not installed.
Fix: Install @code-yeongyu/comment-checker
Affects: comment-checker hook
Error Logs
Subagent repeatedly called glob 16/16 times in the recent tool-call window (80% threshold). This usually indicates an infinite loop. The task was automatically cancelled to prevent excessive token usage.
Subagent repeatedly called bash 16/16 times in the recent tool-call window (80% threshold). This usually indicates an infinite loop. The task was automatically cancelled to prevent excessive token usage.
Configuration
Current stopgap mitigation on my side is config-only, not a code patch:
{
"background_task": {
"staleTimeoutMs": 1800000,
"messageStalenessTimeoutMs": 1800000,
"syncPollTimeoutMs": 1800000,
"circuitBreaker": {
"maxToolCalls": 400,
"windowSize": 60,
"repetitionThresholdPercent": 100
}
},
"agents": {
"explore": {
"prompt_append": "Codebase exploration may require many search turns in a row. Avoid repeating the same tool call with the same inputs unless you explicitly state why the retry is necessary. After each search burst, synthesize what changed and switch approach if results stop improving."
},
"librarian": {
"prompt_append": "External research may require many search turns in a row. Avoid repeating the same tool call with the same inputs unless you explicitly state why the retry is necessary. After each search burst, synthesize what changed and switch approach if results stop improving."
}
}
}
This reduces the false positives enough to keep working, but it is only a temporary workaround.
Additional Context
Relevant source paths in current dev:
src/features/background-agent/manager.ts
src/features/background-agent/loop-detector.ts
src/features/background-agent/manager-circuit-breaker.test.ts
src/cli/run/types.ts
From reading those files, the current repetitive-tool detection appears to count repeated tool names in a sliding window, while tool events already expose input state. That makes grep(query=A), grep(query=B), and grep(query=C) look like the same repeated action.
A likely fix would be to detect repeated (tool name + normalized input) signatures instead of tool name alone, while still keeping the absolute maxToolCalls breaker as the final backstop.
Operating System
macOS
OpenCode Version
1.2.27
This issue was drafted with help from an AI coding agent after reproducing the behavior locally and inspecting the relevant source paths. I reviewed the contents before posting. Marking it as agent-generated for clarity.
Prerequisites
Bug Description
Background subagents such as
exploreandlibrarianare being cancelled by the repetitive-tool circuit breaker during legitimate research/search bursts.The detector appears to treat repeated use of the same tool name as an infinite loop even when the inputs differ materially, which is common for
glob,grep,bash, and similar exploration tools.Steps to Reproduce
exploreto search broadly across a codebase, or askslibrarianto inspect an external repo/docs with many search/tool turns.Two concrete reproductions from my session:
Expected Behavior
Search-heavy agents should be allowed to use the same tool many times in a row when the inputs differ and progress is still being made.
A real loop detector should still catch repeated identical or near-identical tool calls, but it should not kill healthy exploration solely because the tool name repeats.
Actual Behavior
The background circuit breaker cancels the subagent mid-task, which prevents
explore/librarianfrom finishing legitimate investigations.Doctor Output
Error Logs
Configuration
Current stopgap mitigation on my side is config-only, not a code patch:
{ "background_task": { "staleTimeoutMs": 1800000, "messageStalenessTimeoutMs": 1800000, "syncPollTimeoutMs": 1800000, "circuitBreaker": { "maxToolCalls": 400, "windowSize": 60, "repetitionThresholdPercent": 100 } }, "agents": { "explore": { "prompt_append": "Codebase exploration may require many search turns in a row. Avoid repeating the same tool call with the same inputs unless you explicitly state why the retry is necessary. After each search burst, synthesize what changed and switch approach if results stop improving." }, "librarian": { "prompt_append": "External research may require many search turns in a row. Avoid repeating the same tool call with the same inputs unless you explicitly state why the retry is necessary. After each search burst, synthesize what changed and switch approach if results stop improving." } } }This reduces the false positives enough to keep working, but it is only a temporary workaround.
Additional Context
Relevant source paths in current
dev:src/features/background-agent/manager.tssrc/features/background-agent/loop-detector.tssrc/features/background-agent/manager-circuit-breaker.test.tssrc/cli/run/types.tsFrom reading those files, the current repetitive-tool detection appears to count repeated tool names in a sliding window, while tool events already expose input state. That makes
grep(query=A),grep(query=B), andgrep(query=C)look like the same repeated action.A likely fix would be to detect repeated
(tool name + normalized input)signatures instead of tool name alone, while still keeping the absolutemaxToolCallsbreaker as the final backstop.Operating System
macOS
OpenCode Version
1.2.27