Description
The doom_loop check in packages/opencode/src/session/processor.ts (around line 353 on dev) only reads the parts of the current assistant message:
const parts = yield* MessageV2.parts(ctx.assistantMessage.id)
const recentParts = parts.slice(-DOOM_LOOP_THRESHOLD)
Each step is its own assistant message. When the model makes one tool call per step, that message holds [step-start, tool] at the time of the check, so recentParts.length is 2 and the check returns early. The guard cannot fire however many times a call repeats across steps. It only catches three identical calls inside a single response.
This was reported in #25254, which the stale bot closed with a request to open a new issue if it was still relevant. It is still present in v1.18.33 and on dev. PR #32089 changes the check to count matching tool parts across the session and has been open since June. #45442 looks like the same cause, seen from a subagent.
What we saw. v1.18.33, local model through @ai-sdk/openai-compatible. In an 83-step session, every assistant message had exactly three parts: step-start, one tool, step-finish. From step 13 on, the model alternated between two bash calls about 70 times over roughly 10 minutes, until it was cancelled. Two user messages sent during the loop, one pointing it out and one redirecting the task, did not change the next call. The log has no doom_loop evaluation for the session. An earlier session on v1.18.32 alternated between two commands for 183 calls in the same way.
The alternation is also the pattern in #47759, but the scope problem hides it first: even a single command repeated once per step is never seen.
Plugins
None
OpenCode version
1.18.33 (also seen on 1.18.32)
Steps to reproduce
- Leave
doom_loop at its default (ask).
- Use a model that makes one tool call per response, e.g. a local model through
@ai-sdk/openai-compatible.
- Get it to issue the same
bash call with identical input in three or more consecutive steps.
- No
doom_loop prompt appears. In the session DB, each step's assistant message has parts [step-start, tool, step-finish].
Operating System
Ubuntu 24.04.5 LTS
Description
The
doom_loopcheck inpackages/opencode/src/session/processor.ts(around line 353 ondev) only reads the parts of the current assistant message:Each step is its own assistant message. When the model makes one tool call per step, that message holds
[step-start, tool]at the time of the check, sorecentParts.lengthis 2 and the check returns early. The guard cannot fire however many times a call repeats across steps. It only catches three identical calls inside a single response.This was reported in #25254, which the stale bot closed with a request to open a new issue if it was still relevant. It is still present in v1.18.33 and on
dev. PR #32089 changes the check to count matching tool parts across the session and has been open since June. #45442 looks like the same cause, seen from a subagent.What we saw. v1.18.33, local model through
@ai-sdk/openai-compatible. In an 83-step session, every assistant message had exactly three parts:step-start, onetool,step-finish. From step 13 on, the model alternated between twobashcalls about 70 times over roughly 10 minutes, until it was cancelled. Two user messages sent during the loop, one pointing it out and one redirecting the task, did not change the next call. The log has nodoom_loopevaluation for the session. An earlier session on v1.18.32 alternated between two commands for 183 calls in the same way.The alternation is also the pattern in #47759, but the scope problem hides it first: even a single command repeated once per step is never seen.
Plugins
None
OpenCode version
1.18.33 (also seen on 1.18.32)
Steps to reproduce
doom_loopat its default (ask).@ai-sdk/openai-compatible.bashcall with identical input in three or more consecutive steps.doom_loopprompt appears. In the session DB, each step's assistant message has parts[step-start, tool, step-finish].Operating System
Ubuntu 24.04.5 LTS