openclaw - 💡(How to fix) Fix Main-session heartbeat can enter repeated heartbeat_respond loop and cause massive token usage

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…

A main-session heartbeat poll can run inside agent:main:main with full accumulated context and repeatedly call heartbeat_respond in the same turn. In one observed run, this caused massive token usage without user-visible work.

Root Cause

The model kept issuing identical heartbeat_respond tool calls hundreds of times. Because the turn ran in the main session, each iteration carried a large context/cache read cost.

Fix Action

Fix / Workaround

Local mitigation applied

RAW_BUFFERClick to expand / collapse

Summary

A main-session heartbeat poll can run inside agent:main:main with full accumulated context and repeatedly call heartbeat_respond in the same turn. In one observed run, this caused massive token usage without user-visible work.

Observed incident

  • Time: 2026-05-24 14:51:22 to 16:12:28 (+0800)
  • Session key: agent:main:main
  • Trigger: [OpenClaw heartbeat poll]
  • Tool sequence: 2 exec calls followed by 810 repeated heartbeat_respond calls
  • Usage in that single heartbeat turn:
    • totalTokens: 102,373,365
    • cacheRead: 102,160,960
    • input: 157,922
    • output: 54,483
  • Repeated payload was effectively the same no-op summary: git clean, daily memory exists, no async tasks pending.

Expected behavior

  • heartbeat_respond should be terminal for a heartbeat turn, or at least callable only once per turn.
  • Heartbeat polls should not run periodic maintenance inside the long-lived main chat context by default.
  • If a heartbeat turn starts looping tool calls, runtime should abort based on a safe guardrail.

Actual behavior

The model kept issuing identical heartbeat_respond tool calls hundreds of times. Because the turn ran in the main session, each iteration carried a large context/cache read cost.

Suggested fixes

  1. Treat heartbeat_respond as terminal for heartbeat system events.
  2. Add a per-turn guard: max one heartbeat_respond call.
  3. Prefer isolated/light context for periodic heartbeat work instead of agent:main:main.
  4. Add built-in safeguards for heartbeat turns, such as max tool calls and timeout abort.
  5. Consider making comment-only/empty HEARTBEAT.md skip all model calls, and document this as the recommended way to disable main heartbeat tasks.

Local mitigation applied

  • Disabled main-session heartbeat workload by making HEARTBEAT.md comment-only.
  • Moved daily maintenance to isolated/light cron jobs with restricted tools.

No secrets are included in this report.

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…

FAQ

Expected behavior

  • heartbeat_respond should be terminal for a heartbeat turn, or at least callable only once per turn.
  • Heartbeat polls should not run periodic maintenance inside the long-lived main chat context by default.
  • If a heartbeat turn starts looping tool calls, runtime should abort based on a safe guardrail.

Still need to ship something?

×6

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

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix Main-session heartbeat can enter repeated heartbeat_respond loop and cause massive token usage