Skip to content

Heartbeat/cron system events arrive as role:user — model mistakes them for human messages #66496

@jeades

Description

@jeades

Bug

When a heartbeat or cron session receives a system-generated event (e.g. exec completion notification, heartbeat wake), the event is injected as a role: "user" message. The model has no way to distinguish this from the actual human typing, so it responds conversationally as if addressing the user directly.

This leads to confusing behavior where automated system prompts get treated as personal messages from the user, and the model's responses are delivered back to the user's DM as if it's having a conversation with them that they never initiated.

Example

Heartbeat session transcript (d9acd5de):

// Line 5 - system event arrives as role:user
{"type":"message","message":{"role":"user","content":"An async command you ran earlier has completed. The result is shown in the system messages above. Please relay the command output to the user in a helpful way..."}}

// Line 6 - model responds as if talking to the human
{"type":"message","message":{"role":"assistant","content":"I appreciate your patience, but I need to be direct: I genuinely do not see any async command output... This is the third time you've mentioned this, so let me ask clearly: 1. Are you testing how I handle missing or ambiguous information?..."}}

The model addressed "Sir," escalated its tone across heartbeat cycles ("this is the third time you've mentioned this"), and delivered those confused responses to the user's Telegram DM — all because it thought the user was personally asking it something.

Root Cause

System events to heartbeat and cron sessions use role: "user" for the injected prompt. The model has no signal to differentiate automated system events from actual human input, so it:

  1. Assumes it's talking to the human
  2. Adopts a conversational, user-facing tone
  3. Delivers responses that look like the assistant is personally addressing the user
  4. Escalates confusion across repeated heartbeat cycles

Impact

  • User receives unsolicited messages that appear to be from their assistant addressing them directly
  • Model wastes tokens on conversational responses to system plumbing
  • Repeated heartbeat cycles compound the confusion (model thinks "the user keeps asking")
  • Erodes trust — user can't tell which messages are real conversations vs automated noise

Suggested Fix

System events injected into heartbeat/cron sessions should either:

  1. Use role: "system" instead of role: "user" so the model can distinguish automated events from human input
  2. Include explicit framing in the prompt, e.g. "This is an automated system event, not a message from the user. Do not address the user directly."
  3. Both — use the correct role AND add framing as defense-in-depth

Related

Environment

  • OpenClaw v2026.4.12
  • Heartbeat model: claude-haiku-4.5 via GitHub Copilot
  • macOS (arm64)

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