Skip to content

fix(processor): fix doom loop detection scope and filter order#25255

Open
qz1543706741 wants to merge 1 commit intoanomalyco:devfrom
qz1543706741:fix/doom-loop-cross-message-detection
Open

fix(processor): fix doom loop detection scope and filter order#25255
qz1543706741 wants to merge 1 commit intoanomalyco:devfrom
qz1543706741:fix/doom-loop-cross-message-detection

Conversation

@qz1543706741
Copy link
Copy Markdown

Issue for this PR

Closes #25254

Type of change

  • Bug fix

What does this PR do?

Fixes two bugs in the doom loop detection logic in packages/opencode/src/session/processor.ts.

Bug 1 — detection scope limited to current message only

// before
const parts = MessageV2.parts(ctx.assistantMessage.id)
const recentParts = parts.slice(-DOOM_LOOP_THRESHOLD)

MessageV2.parts(ctx.assistantMessage.id) only returns parts from the current assistant message. When a model repeats the same tool call across multiple messages in a session (e.g. three separate turns each calling read_file with the same path), the doom loop is never detected because each individual message has fewer than DOOM_LOOP_THRESHOLD matching parts.

Fix: use MessageV2.filterCompactedEffect(ctx.sessionID) to search all messages since the last user turn, collecting matching tool parts across message boundaries.

Bug 2 — slice before filter inverts the logic

// before
parts.slice(-DOOM_LOOP_THRESHOLD).every(part => part.type === "tool" && part.tool === value.toolName && ...)

Taking the last N parts first (which may include text or reasoning parts) and then checking whether all N match means that if any non-tool part appears in the tail, every returns false and the doom loop check silently passes. The correct order is: filter matching tool parts first, then check if the count reaches the threshold.

Fix: introduced recentMatchingToolParts which filters by tool + JSON(args) first, then slices to DOOM_LOOP_THRESHOLD.

How did you verify your code works?

Reviewed the diff against upstream/dev. MessageV2.filterCompactedEffect and ProcessorContext.sessionID are both present in the current codebase. No new dependencies introduced.

Screenshots / recordings

N/A — logic-only change with no UI impact.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 1, 2026

The following comment was made by an LLM, it may be inaccurate:

The search results show PR #25255 (the current PR) and related PRs about doom loop optimization. Let me verify if any of these are actual duplicates by checking PRs #20288 and #20303 which mention doom loop detection optimization:

No duplicate PRs found

Bojun-Vvibe added a commit to Bojun-Vvibe/oss-contributions that referenced this pull request May 1, 2026
- anomalyco/opencode#25255: doom loop scope+filter-order fix (merge-as-is)
- openai/codex#20577: store-history fork migration (merge-after-nits)
- openai/codex#20528: skill-scoped hooks feature (merge-after-nits)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(processor): doom loop detection misses cross-message repetitions and has inverted filter order

1 participant