hermes - 💡(How to fix) Fix [RFC] ToolCallStormBreaker — suppress repeated tool-call loops

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Error Message

A lightweight sliding-window detector that tracks the last 8 (tool_name, args_signature) pairs. When the same pair appears ≥3 times, subsequent identical calls are suppressed: instead of executing the tool, an error result is injected telling the model to try a different approach.

Fix Action

Fix / Workaround

Key design decisions:

  • Storm-exempt tools (read_file, search_files, web_search, browser_snapshot, etc.) are never suppressed — the model legitimately re-reads after the world changes.
  • Mutating tools (write_file, patch, terminal, etc.) reset the storm window on execution, since a world-changing action may legitimately warrant re-reading.
  • Sliding window across turns, not just within one assistant response — the loop can span multiple turns.
  • Per-conversation lifetime, so a storm in one session doesn't poison the next.
RAW_BUFFERClick to expand / collapse

Problem

When the model gets into a loop calling the same tool with identical arguments (e.g. reading a file that hasn't changed, retrying a failed operation without variation), the conversation burns tokens and frustrates users. These loops can run 5-10+ iterations before the model spontaneously breaks out.

Proposed solution

A lightweight sliding-window detector that tracks the last 8 (tool_name, args_signature) pairs. When the same pair appears ≥3 times, subsequent identical calls are suppressed: instead of executing the tool, an error result is injected telling the model to try a different approach.

Key design decisions:

  • Storm-exempt tools (read_file, search_files, web_search, browser_snapshot, etc.) are never suppressed — the model legitimately re-reads after the world changes.
  • Mutating tools (write_file, patch, terminal, etc.) reset the storm window on execution, since a world-changing action may legitimately warrant re-reading.
  • Sliding window across turns, not just within one assistant response — the loop can span multiple turns.
  • Per-conversation lifetime, so a storm in one session doesn't poison the next.

I've been running this for about a week in daily use. The most common catch: the model keeps calling read_file on a file whose content didn't change between reads → storm-exempt handles that. The next most common: repeated web_search with the same query → caught and suppressed with "try a different query or approach."

The implementation is ~90 lines in agent/tool_executor.py plus ~40 lines in agent/conversation_loop.py. Happy to open a PR if this sounds useful.

Prior art

The idea is adapted from Reasonix's StormBreaker (repair/storm.ts), which has been in production for several months and proven effective at catching tool-call loops in practice.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - 💡(How to fix) Fix [RFC] ToolCallStormBreaker — suppress repeated tool-call loops