Skip to content

Internal exec/heartbeat events leak into visible Control UI chat transcript #66814

@mandomaker

Description

@mandomaker

Summary

Internal async exec completion and heartbeat/system wake material is leaking into visible Control UI/webchat chat history as normal chat messages.

This is not just a local rendering issue. The behavior appears to come from upstream event/session classification, with internal exec-event and heartbeat followups being replayed or serialized into normal visible chat flows.

User-visible symptoms

Users see messages like:

  • System (untrusted): Exec completed (...) :: ...
  • An async command you ran earlier has completed. The result is shown in the system messages above...
  • heartbeat/system-style prompt text appearing directly inside the main chat transcript

These messages pollute the main conversation and feel like broken internal plumbing surfacing to the user.

What we observed

  • chat.history for the session can appear cleaner than the live chat stream, which suggests more than one leak path.
  • Mission Control transcript-level filtering can hide some of this, but the actual live user chat still receives it.
  • Repeated local bundle patches against UI-level suppression and selected heartbeat code paths did not fully solve the problem.
  • This strongly suggests multiple upstream leak paths.

Likely leak paths

1. Internal/system material entering visible history

Heartbeat/exec-event followups appear to be getting stored or replayed as ordinary visible chat messages.

2. Live websocket/chat stream emitting internal activity as normal chat

Control UI appears to render live chat events that include internal heartbeat/exec/system followups as if they were normal user-facing chat messages.

Likely root cause

The async exec completion flow appears to:

  1. enqueue a system event such as Exec completed (...) :: ...
  2. trigger heartbeat handling with reason exec-event
  3. heartbeat builds a synthetic prompt/turn from queued system events
  4. that internal prompt/reply path can become visible chat instead of staying internal
  5. processed events may be peeked/replayed instead of being fully consumed/drained

Relevant runtime areas we inspected in the installed bundle included:

  • bash-tools.exec-runtime-*.js
  • server-node-events-*.js
  • heartbeat-runner-*.js
  • session-system-events-*.js
  • sessions-history-http-*.js
  • transcript/session append paths

Strong indicators this is upstream and not unique to one setup

The behavior is consistent with prior issue reports involving:

  • heartbeat wakeups persisting into dashboard/main session as synthetic visible messages
  • exec-completion heartbeat handling using queued system events in a way that can replay them later

Recommended durable fix

Backend first

Internal exec-event / heartbeat / wake followups should never become ordinary visible transcript entries in the user session.

Recommended approach:

  1. Keep exec completion and heartbeat wake handling on an internal event lane, not the visible user transcript lane.
  2. Drain/consume processed exec-event system entries after handling, instead of leaving them available for replay.
  3. Prevent synthetic heartbeat/system prompts from being serialized into normal chat.history message kinds.
  4. Distinguish visible transcript messages from internal event-stream items in gateway/session mapping.

UI second

Control UI should still defensively filter internal event items, but only as defense in depth. UI-only content suppression is not sufficient because new variants and upstream replay paths still leak through.

Why this matters

This bug makes OpenClaw feel unstable and breaks trust in the chat surface, especially for users who rely heavily on async exec workflows. The more async/background work they do, the more spam they see.

Reproduction shape

A practical repro pattern is:

  1. run an async/background exec task
  2. let it complete
  3. observe main Control UI/webchat chat transcript
  4. internal exec completion / heartbeat followup text appears in visible chat

Expected behavior

  • async exec completion should remain internal unless the assistant explicitly decides to summarize it to the user
  • heartbeat/system prompts should never surface verbatim to the user
  • visible main chat should contain only true user/assistant conversation content

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