Skip to content

notifyOnExit wake reason doesn't bypass empty HEARTBEAT.md guard #41406

@eoksen

Description

@eoksen

Bug

When a backgrounded exec session exits, notifyOnExit calls requestHeartbeatNow({ reason: \exec:${session.id}:exit` }). However, the heartbeat execution path skips turns when HEARTBEAT.mdis effectively empty, and only bypasses that guard for specific reason strings:exec-event, wake, hook:, cron:`.

The reason exec:<id>:exit doesn't match any of these, so the heartbeat is skipped entirely. The system event remains queued until the next user message.

Expected behavior

Background exec completion should trigger an agent turn even when HEARTBEAT.md is empty, since the system event contains actionable information the agent needs to process.

Observed behavior

  • Agent dispatches background exec (coding agent), exits after ~18 minutes
  • notifyOnExit enqueues system event and requests heartbeat with reason exec:<session-id>:exit
  • Heartbeat handler sees empty HEARTBEAT.md, reason doesn't match bypass list → skips
  • System event sits in queue for 70+ minutes until user sends next message
  • Event is then bundled into the user's message turn

Suggested fix

Change notifyOnExit to use exec-event as the wake reason, which already has dedicated heartbeat behavior:

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

Or extend the bypass check to recognize exec: prefixed reasons:

const isExecEventReason = opts.reason === "exec-event" || Boolean(opts.reason?.startsWith("exec:"));

Secondary issue

Even when a heartbeat does fire with pending system events, if the model responds HEARTBEAT_OK, the drained system events are silently consumed with no user-visible output. Consider re-enqueueing drained events when the heartbeat normalizes to ack-only.

Environment

  • OpenClaw 2026.2.17
  • Empty HEARTBEAT.md (comments only)

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