Skip to content

Agent enters non-terminating loop, repeats identical tool calls and burns tokens #43673

Closed

Description

@rafaelxy

Description

While investigating a plugin auto-update toast, the agent got stuck in a non-terminating loop: it issued the same tool call (grep on the same file path) dozens of times in a row, each returning identical output, with no progress toward the task. It only stopped when I aborted the session. This burned a large amount of tokens with zero forward progress. There was no error, no retry/backoff, and no loop-detection — the agent just kept re-issuing the identical call.

Plugins

@cortexkit/opencode-magic-context@latest, @dietrichgebert/ponytail@latest, opencode-adaptive-thinking, oh-my-opencode-slim, @xberg-io/* (xberg, crawlberg, html-to-markdown, liter-llm, tree-sitter-language-pack), opencode-chrome-devtools, opencode-subagent-statusline (tui.json)

OpenCode version

1.18.19

Steps to reproduce

I could not reproduce, but those were the steps:

  1. Open opencode in a project with the magic-context plugin configured as @cortexkit/opencode-magic-context@latest in opencode.json (not in tui.json).
  2. Ask the agent to investigate the "Magic Context update failed" startup toast.
  3. The agent begins reading the plugin's bundled dist/index.js and repeatedly re-runs the same grep command on the same file, dozens of times, never converging.

Screenshot and/or share link

Loop log excerpt — session ses_fe06fd054ffe5bv9vlIlDYhkcU

Source: ~/.local/share/opencode/log/opencode.log (opencode 1.18.19, macOS 26.6.1, iTerm2)
Loop window: 2026-08-20 14:26:32 → 15:17:49 UTC (~51 min), aborted by user.

Stats (loop window)

  • Loop steps: step=14 → step=527 (514 iterations)
  • Identical grep -rn "auto_update" .../src/ calls: 502
  • Identical ls .../src/ calls: 492
  • No error, no backoff, no loop detection — the agent re-issued the same tool call until cancelled.

Sample — 6 consecutive identical tool calls (15:17:21 → 15:17:45)

timestamp=2026-08-20T15:17:21.074Z level=INFO run=d3ab2e61 message=evaluated permission=bash pattern="grep -rn \"auto_update\" ~/.cache/opencode/packages/@cortexkit/opencode-magic-context@latest/node_modules/@cortexkit/opencode-magic-context/src/ 2>/dev/null" action.permission=bash action.pattern=* action.action=allow
timestamp=2026-08-20T15:17:21.074Z level=INFO run=d3ab2e61 message=evaluated permission=bash pattern="ls ~/.cache/opencode/packages/@cortexkit/opencode-magic-context@latest/node_modules/@cortexkit/opencode-magic-context/src/" action.permission=bash action.pattern=* action.action=allow
timestamp=2026-08-20T15:17:27.408Z level=INFO run=d3ab2e61 message=evaluated permission=bash pattern="grep -rn \"auto_update\" ~/.cache/opencode/packages/@cortexkit/opencode-magic-context@latest/node_modules/@cortexkit/opencode-magic-context/src/ 2>/dev/null" action.permission=bash action.pattern=* action.action=allow
timestamp=2026-08-20T15:17:27.410Z level=INFO run=d3ab2e61 message=evaluated permission=bash pattern="ls ~/.cache/opencode/packages/@cortexkit/opencode-magic-context@latest/node_modules/@cortexkit/opencode-magic-context/src/" action.permission=bash action.pattern=* action.action=allow
timestamp=2026-08-20T15:17:32.459Z level=INFO run=d3ab2e61 message=evaluated permission=bash pattern="grep -rn \"auto_update\" ~/.cache/opencode/packages/@cortexkit/opencode-magic-context@latest/node_modules/@cortexkit/opencode-magic-context/src/ 2>/dev/null" action.permission=bash action.pattern=* action.action=allow
timestamp=2026-08-20T15:17:32.459Z level=INFO run=d3ab2e61 message=evaluated permission=bash pattern="ls ~/.cache/opencode/packages/@cortexkit/opencode-magic-context@latest/node_modules/@cortexkit/opencode-magic-context/src/" action.permission=bash action.pattern=* action.action=allow
timestamp=2026-08-20T15:17:41.041Z level=INFO run=d3ab2e61 message=evaluated permission=bash pattern="grep -rn \"auto_update\" ~/.cache/opencode/packages/@cortexkit/opencode-magic-context@latest/node_modules/@cortexkit/opencode-magic-context/src/ 2>/dev/null" action.permission=bash action.pattern=* action.action=allow
timestamp=2026-08-20T15:17:41.041Z level=INFO run=d3ab2e61 message=evaluated permission=bash pattern="ls ~/.cache/opencode/packages/@cortexkit/opencode-magic-context@latest/node_modules/@cortexkit/opencode-magic-context/src/" action.permission=bash action.pattern=* action.action=allow
timestamp=2026-08-20T15:17:45.392Z level=INFO run=d3ab2e61 message=evaluated permission=bash pattern="grep -rn \"auto_update\" ~/.cache/opencode/packages/@cortexkit/opencode-magic-context@latest/node_modules/@cortexkit/opencode-magic-context/src/ 2>/dev/null" action.permission=bash action.pattern=* action.action=allow

Loop step progression (start → end)

message=loop session.id=ses_fe06fd054ffe5bv9vlIlDYhkcU step=14   (14:26:32)
message=loop session.id=ses_fe06fd054ffe5bv9vlIlDYhkcU step=527  (15:17:45)

Termination (user abort)

timestamp=2026-08-20T15:17:49.909Z level=INFO run=d3ab2e61 message=cancel session.id=ses_fe06fd054ffe5bv9vlIlDYhkcU
timestamp=2026-08-20T15:17:49.920Z level=ERROR run=d3ab2e61 message=process session.id=ses_fe06fd054ffe5bv9vlIlDYhkcU messageID=msg_01fbfe8600016IVReGRIF4SXc0 e...

Operating System

macOS 26.6.1

Terminal

iTerm2

Activity

  1. github-actions commented on Aug 20, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    If your issue adds new context (e.g., the specific plugin interaction or the 51-minute / 514-iteration scale), please mention that on the existing issue rather than opening a new one.

  2. jagnd1 commented on Aug 21, 2026

    @jagnd1

    Confirmed same class of bug in a fresh session with NO plugins, opencode 1.18.19, model opencode-go/deepseek-v4-flash (macOS ARM64). This rules out a plugin-triggered cause and suggests a general missing loop-detection issue.

    Findings / observations:

    1. Triggers were not all identical in shape — observed loops where the agent re-issued:
      • the same file read repeatedly,
      • the same git add/git commit repeatedly,
      • the same git status check repeatedly.
        In every case it re-emitted an identical tool call instead of executing once and moving on, with no self-correction until interrupted.
    2. It is intermittent, not deterministic — a long multi-phase task (many sequential edits/commits/tests) progressed normally for a while, then entered a loop, then after interruption resumed normally.
    3. Mitigation that worked for us: interrupting immediately (at the 2nd repeat) and issuing one explicit command per step (rather than letting it chain/repeat) let the work continue. Adding a hard rule "never repeat the same tool call twice; move on" to the session guidance also reduced occurrences.
    4. Impact: each repetition consumes tokens; in a billing-metered session this caused significant token/billing swell and stalled progress.

    Environment: opencode 1.18.19, deepseek-v4-flash, macOS 25.5.0 (Darwin ARM64/T6020), Node v26.5.0, no plugins.

    Hope the loop/no-progress detection + circuit breaker (as referenced in #31942) lands soon.

  3. agentgoblin commented on Aug 27, 2026

    @agentgoblin

    How about doom_loop permission? #45442 (comment)

  4. jagnd1 commented on Aug 29, 2026

    @jagnd1

    Thanks @agentgoblin — the doom_loop pointer (#45442) was exactly it. I've verified on opencode 1.18.20 / deepseek-v4-flash:

    • With "permission": { "doom_loop": "deny" }, prompting five identical ls -la calls, the 3rd identical call is blocked (...prevents you from using this specific tool call... doom_loop deny) and the session ends instead of looping.
    • Your framing is right: the root cause is long-context degenerate repetition in the model, but the framework must protect against it — doom_loop is that protection.

    For anyone hitting the identical-call loop: set doom_loop to deny (the default is ask, which won't protect --auto/unattended sessions). This covers the 514-iteration grep/ls case here and the read/git loops in #43800.

    Appreciate the fast help — leaving this issue open for @rafaelxy to weigh in if they want to add their repro/close it too.

  5. rafaelxy commented on Aug 31, 2026

    @rafaelxy
    Author

    @jagnd1 @agentgoblin Thanks the doom_loop seems fitting and I enabled it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions