Skip to content

[Bug]: Heartbeat runs create duplicate response branches when enqueued as followups #25606

@mcaxtr

Description

@mcaxtr

Summary

Heartbeat runs arriving while another agent run is active get enqueued as followups, and when the queue drains, they produce duplicate agent runs that send multiple response branches to users.

Steps to reproduce

  1. Configure heartbeat with any model (e.g., gpt-4o-mini or ministral-3b)
  2. Enable heartbeat runner with default settings in agent config
  3. Trigger a heartbeat check while another agent run is already active for the same session
  4. Observe the followup queue drain after the active run completes

Expected behavior

A heartbeat check should send exactly one message:

  • Either HEARTBEAT_OK if nothing needs attention
  • Or a single brief status update if something needs attention

Actual behavior

Multiple messages are sent to the user because:

  1. The heartbeat run arrives while isActive: true
  2. Current code at src/auto-reply/reply/agent-runner.ts:238-243 enqueues it via enqueueFollowupRun() when shouldFollowup is true
  3. When the active run completes and the followup queue drains, the stale heartbeat executes as a new agent run
  4. This produces additional response branches that get delivered to the user

The followup mechanism (finalizeWithFollowup()) spawns a new agent run with a different parentId, creating extra response branches.

OpenClaw version

2026.2.23 (current main branch)

Operating system

Linux / macOS / all platforms

Install method

npm global / pnpm dev / mac app (all affected)

Logs, screenshots, and evidence

Current code in src/auto-reply/reply/agent-runner.ts:

if (isActive && (shouldFollowup || resolvedQueue.mode === "steer")) {
  enqueueFollowupRun(queueKey, followupRun, resolvedQueue);
  await touchActiveSessionEntry();
  typing.cleanup();
  return undefined;
}

This enqueues ALL runs (including heartbeat) when another run is active, causing the duplicate branch issue.

Impact and severity

Affected: All users with heartbeat enabled, all channels
Severity: High - creates user-visible duplicate messages and poor UX
Frequency: Happens whenever a heartbeat interval coincides with an active agent run
Consequence: Users receive 2-4 messages instead of 1, creating confusion and noise

Additional information

This is a recreation of closed issue #8063 and PR #12786, which were automatically closed as "stale" despite the fix never being merged to main. The original issue was valid and the fix is still needed.

The fix requires adding an early-return guard specifically for heartbeat runs before they reach the enqueue logic, allowing the next heartbeat interval to independently re-check the session.

Metadata

Metadata

Assignees

No one assigned

    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