Skip to content

bug: built-in heartbeat only runs in main session — causes inevitable context bloat with no escape hatch #20011

@AlexChen31337

Description

@AlexChen31337

Summary

The built-in heartbeat feature accumulates conversation turns in the main session with no way to isolate it. Over time (2+ days of hourly heartbeats), the session .jsonl file grows to 10–15MB, corrupts, and triggers an automatic reset — silently wiping all agent context.

Root Cause

heartbeat.session config only supports "main" — there is no "isolated" option. Every heartbeat turn is permanently stored in the main session history and re-sent to the LLM on every subsequent request, inflating token cost and file size indefinitely.

Reproduction

  1. Set heartbeat.every: "1h" (or any interval)
  2. Run OpenClaw for 2+ days
  3. Observe ~/.openclaw/agents/main/sessions/<main-session-id>.jsonl growing 5–15MB
  4. Eventually the session file corrupts (header truncation) and OpenClaw auto-resets — all context lost

Impact

  • Context window bloated by hundreds of accumulated heartbeat turns
  • Token cost inflates proportionally on every new request
  • Silent context loss when session eventually resets
  • No warning, no user-facing indicator

Workaround

Disable built-in heartbeat entirely (heartbeat.every: "0m") and replace with a cron job using sessionTarget: "isolated":

{
  "schedule": {"kind": "every", "everyMs": 3600000},
  "payload": {"kind": "agentTurn", "model": "<cheap-model>", "message": "..."},
  "sessionTarget": "isolated"
}

This works but is a significant usability gap — the built-in heartbeat is the obvious first-choice for periodic monitoring.

Requested Fix

Add heartbeat.session: "isolated" config option that runs heartbeat in a fresh isolated session, preventing main session pollution. Alternatively, add an automatic session file size cap or rolling compaction triggered by file size rather than token count alone.

Environment

  • OpenClaw version: 2026.2.13
  • Platform: Linux x64
  • Heartbeat interval: hourly
  • Time to failure: ~2 days

Metadata

Metadata

Assignees

No one assigned

    Labels

    staleMarked as stale due to inactivity

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions