Skip to content

Subagent background exec triggers spurious heartbeat wake-ups on main session #66748

@ggzeng

Description

@ggzeng

Problem

When a subagent runs background exec commands (e.g. background: true), each exec completion triggers requestHeartbeatNow({reason: "exec-event"}). The heartbeat runner's resolveHeartbeatSession falls back subagent session keys to the main session, causing spurious heartbeat wake-ups on the parent agent.

This results in:

  • Frequent unnecessary LLM calls (one per subagent exec completion)
  • Spurious HEARTBEAT_OK messages appearing in the main session (visible in WebChat)
  • Wasted API tokens

Reproduction

  1. Open WebChat for the main agent
  2. Spawn a subagent that runs multiple background exec commands:
    sessions_spawn(task: "...", mode: "run")
    
  3. Observe the main session receiving HEARTBEAT_OK responses every 60-90 seconds

Root Cause

In src/agents/bash-tools.exec-runtime.ts, both maybeNotifyOnExit() and emitExecSystemEvent() unconditionally call:

requestHeartbeatNow(scopedHeartbeatWakeOptions(sessionKey, { reason: "exec-event" }));

In src/infra/heartbeat-runner.ts, resolveHeartbeatSession() (line 253) falls back subagent session keys:

if (!trimmed || isSubagentSessionKey(trimmed)) {
    return { sessionKey: mainSessionKey, ... };
}

This is redundant because:

  • Subagents receive exec results via normal process poll — they are actively waiting
  • Subagent completion is communicated to the parent via subagent_announce
  • The heartbeat provides no value for subagent sessions

Proposed Fix

Guard the requestHeartbeatNow calls with isSubagentSessionKey:

if (!isSubagentSessionKey(sessionKey)) {
  requestHeartbeatNow(scopedHeartbeatWakeOptions(sessionKey, { reason: "exec-event" }));
}

PR incoming.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    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