anomalyco / anomalyco/opencode

subagent: infinite loop of identical tool calls for ~50min with no loop protection, uncontrollable token burn

Open
#45,442 8 comments 2 reactions 1 assignee View on GitHub

@rekram1-node is already working on this.

Since Aug 27, 2026.

2.0
Dominant language
TypeScript
Stars
209k
Forks
27.5k
PR merge metrics
PR metrics pending

Description

Subagent infinite loop: repeated identical tool calls for ~50 min, no loop protection, uncontrollable token burn

Summary

A background general subagent entered an infinite loop: it issued 364 identical grep tool calls (same pattern, same path, same directory) over ~50 minutes with a steady ~5s cadence, burning ~184k input tokens + ~40k output tokens + ~142M cache-read tokens before I manually discovered and interrupted it. OpenCode's agent loop has no repeated-action detection, no step limit, no heartbeat timeout, and the parent session has no way to notice or abort a stuck subagent — it was reported as running the whole time.

Environment

  • opencode version: 0.0.0-beta-18286 (opencode --version reports 1.18.18)
  • OS: Darwin 25.5.0 (macOS 26.5.1, arm64)
  • Terminal: Unavailable: terminal environment variables are not set (running via OpenCode Beta desktop app)
  • Shell: /bin/zsh
  • Install/channel: beta (OpenCode Beta.app, CLI path .../cli/0.0.0-beta-18286/opencode-cli serve --service)
  • Active plugins: None found in config
  • Model: a deepseek-v4-flash variant (via a private/custom OpenAI-compatible provider; details redacted for privacy)

Reproduction

  1. Start a parent session (TUI/desktop).
  2. Spawn a background subagent (general agent) with a large task — in my case: "review a 47KB / 21-file merge request diff", where the subagent cross-verifies claims against source code.
  3. Let it run. The subagent loads a large context (cache-read peaked at ~142M tokens total over the loop) and enters a degenerate mode where it repeatedly decides to execute the same grep call: pattern ErrsSceneConfigNotFound|ErrsSceneConfigFailed, path .../PlanServer, every ~5 seconds.
  4. Observe: 364 consecutive messages with identical tool input, zero progress, session stays running in GET /api/session/active.

Expected Behavior

  • OpenCode should detect repeated identical tool calls (or a step/iteration cap, or a per-session max duration) and either stop the loop, surface a warning to the parent session, or expose a configurable limit.
  • The parent session / API should expose a way to notice a stuck subagent (e.g., heartbeat, last-activity timestamp in session data) and abort it without requiring the user to inspect the raw session database.
  • Background subagents that burn tokens with no progress should not be reported indefinitely as running.

Actual Behavior

  • The subagent ran 364 identical grep calls at a ~5.0s cadence (sampled intervals: 5,5,5,5,5,6,4,6,5,5) for ~50 minutes (10:04:37 → 10:54:26 local).
  • Token burn during the loop: ~184,196 input + ~39,518 output + ~142,413,184 cache-read tokens (from session DB).
  • No built-in detection, limit, warning, or auto-interrupt. GET /api/session/active reported {"ses_...": {"type": "running"}} throughout.
  • I had to discover the loop by querying the SQLite DB (~/.local/share/opencode/opencode.db, table session_message) for repeated tool calls, then manually call POST /api/session/{id}/interrupt using the authenticated HTTP API (credentials from the local service config).

Additional Context

  • Root cause of the repetition is model behavior (a long-context degenerate repetition), but the framework provides zero protection against it — that is the bug.
  • I could not find any documented step limit / max-turns / loop-detection / heartbeat configuration in the config schema; only reasoningEffort variants are present in the provider config.
  • Interrupt endpoint exists (POST /api/session/{sessionID}/interrupt) and works, but it is purely manual/out-of-band; nothing in the framework triggers it.
  • Frequency: observed once so far; reproducible trigger appears to be a long-running background subagent with repeated verification tool calls.
  • Workaround used: manual SQLite inspection + manual HTTP interrupt via opencode2 api post /api/session/{id}/interrupt (or raw curl with Basic auth).

Suggested directions (for maintainers):

  • Add a loop guard: N consecutive identical tool calls (same name + same input hash) → warn or abort (configurable).
  • Add a step/iteration cap per agent turn loop (e.g., maxSteps) with a clear terminal state instead of running.
  • Surface last-activity/heartbeat per session in the API so parents/clients can detect stalls.
  • Allow cancelling background subagents from the parent session UI/API.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.