Summary
Async exec completion events are currently routed through the heartbeat/alert path and end up being rendered into the webchat/control-ui conversation as visible System messages.
This pollutes the user-facing transcript with internal runtime notifications that should not appear as normal chat messages.
Steps to reproduce
- Open OpenClaw Control UI / webchat
- In a normal conversation, trigger one or more async/background
exec calls
- Wait for those commands to finish
- Observe that completion notifications are injected back into the conversation as visible
System (untrusted): Exec completed ... messages
This is especially obvious when multiple background execs are started in a short period, since each completion can generate another visible System message.
Actual behavior
- Async exec completions are surfaced as visible System messages inside the webchat conversation
- These messages are written into the transcript
- They interrupt the normal user/assistant dialogue flow
- In bursty cases, they can spam the conversation with multiple internal completion notices
Expected behavior
- Exec completion events should not be injected into the user-visible webchat transcript by default
- For webchat/control-ui, they should go to a non-transcript surface instead, such as:
- an activity indicator
- a status/event panel
- a toast/notification layer
- If a visible chat message is ever needed, it should be explicit opt-in behavior rather than the default
Why this is a bug
This is not just noisy UX. It also mixes internal runtime events with user conversation history, which makes the transcript harder to read and reason about. In control-ui/webchat, internal execution lifecycle events should be separated from the chat stream.
Suspected cause
Likely cause: async exec completion events are treated as heartbeat/alert events, and the webchat delivery path renders those events back into the active conversation as System messages.
Logs, screenshots, and evidence
Workaround
A temporary workaround is:
"channels": {
"defaults": {
"heartbeat": {
"showOk": false,
"showAlerts": false,
"useIndicator": false
}
}
}
This suppresses the noise, but does not address the underlying issue that internal exec completion events are eligible to enter the chat transcript at all.
Scope
Confirmed in webchat / control-ui.
Not claiming the same behavior is necessarily wrong on every channel.
Summary
Async exec completion events are currently routed through the heartbeat/alert path and end up being rendered into the webchat/control-ui conversation as visible System messages.
This pollutes the user-facing transcript with internal runtime notifications that should not appear as normal chat messages.
Steps to reproduce
execcallsSystem (untrusted): Exec completed ...messagesThis is especially obvious when multiple background execs are started in a short period, since each completion can generate another visible System message.
Actual behavior
Expected behavior
Why this is a bug
This is not just noisy UX. It also mixes internal runtime events with user conversation history, which makes the transcript harder to read and reason about. In control-ui/webchat, internal execution lifecycle events should be separated from the chat stream.
Suspected cause
Likely cause: async exec completion events are treated as heartbeat/alert events, and the webchat delivery path renders those events back into the active conversation as System messages.
Logs, screenshots, and evidence
Workaround
A temporary workaround is:
This suppresses the noise, but does not address the underlying issue that internal exec completion events are eligible to enter the chat transcript at all.
Scope
Confirmed in webchat / control-ui.
Not claiming the same behavior is necessarily wrong on every channel.