First, I want to sincerely apologize for the flood of issues coming from this account. I think OpenClaw is genuinely brilliant, and I want to help make it even better. Thank you to all the maintainers for your outstanding work — this project is exceptional, and reporting bugs is my way of giving back.
Affected version: openclaw@2026.5.27 (running); code present in current dist bundle
Summary
With agents.defaults.compaction.notifyUser: true, the user is supposed to be told when a context compaction happens. But the notice is delivered only through the active turn streaming block-reply callback onBlockReply. The notice function hard-returns when that callback is absent.
Consequence: any compaction that runs outside an active, inbound-driven streaming reply turn — e.g. a proactive maxHistoryShare-triggered compaction, or a compaction inside an announce/embedded run (subagent-completion auto-announce) — has no wired onBlockReply, so sendCompactionNotice returns immediately. No notice is delivered, none is queued, and there is no retry.
Impact
- notifyUser: true gives a false sense of coverage. The user is notified only when a compaction happens to coincide with a live streaming reply turn; the asynchronous / proactive ones — which are the ones a user would most want flagged — produce nothing.
- Failure is silent: the early return logs nothing; even the delivery catch only goes to logVerbose (not visible at default log level).
- It compounds a separate delivery gap (see Related): when a subagent-completion auto-announce is dropped and the surrounding compaction is also unannounced, the user has no signal at all that the conversation state changed underneath them.
Environment
|
|
| openclaw |
2026.5.27 (gateway) |
| platform |
Linux aarch64 (NVIDIA GB10 / Spark) |
| provider |
openai-completions -> vLLM, Qwen/Qwen3.6-27B-FP8 |
| config |
agents.defaults.compaction = { notifyUser: true, maxHistoryShare: 0.3, mode, reserveTokensFloor, memoryFlush } |
| channel |
WhatsApp direct |
Reproduction / observed evidence
Timeline (session bf5ec6e1-..., WhatsApp direct):
- 2026-06-01T04:30:52Z assistant produces a reply (in response to an internal subagent-completion event, not a WhatsApp inbound).
- 2026-06-01T04:34:22Z a compaction record is written to the session — ~3.5 min after the previous turn finished and ~17 min before the next inbound message.
- Gateway log between 04:00-07:00 CEST contains zero auto-compaction start / context overflow detected lines -> this was a proactive / non-overflow compaction.
- The user received no compaction notice, despite notifyUser: true.
The compaction ran with no active inbound streaming turn -> no onBlockReply -> sendCompactionNotice early-returned.
Root cause
The notice is bound to the per-turn streaming callback rather than to the channel/session delivery layer. sendCompactionNotice is only reachable via the three call sites inside the streaming reply path (phase: start | end | incomplete), each guarded by shouldNotifyUserAboutCompaction, and all of them depend on params.opts.onBlockReply being present. Compactions triggered outside that path (proactive maxHistoryShare, embedded/announce runs) have no such callback.
Location (dist bundle): dist/reply-turn-admission-BaGuBaDP.js, function sendCompactionNotice and the three else-if call sites. (Source path inferred: src/agents/.../reply-turn-admission.ts.)
Proposed fix
Decouple the compaction notice from onBlockReply so it can be delivered for any compaction on the session:
- When onBlockReply is unavailable, fall back to a direct channel/session send (the same path used to push subagent auto-announces to the requester session), addressed by sessionKey / channel of the session being compacted.
- Alternatively, emit the notice through the session delivery queue so it is durable and retried.
- At minimum: when notifyUser === true and onBlockReply is absent at notice time, log it at a visible level (not logVerbose) so the gap is observable rather than silent.
Related (separate issue, same family)
In the same session, the assistant reply generated at step 1 (a subagent-completion auto-announce) was itself never delivered to WhatsApp and was not found in delivery-queue/failed. That is the previously known subagent->requester announce-delivery drop — but both share the root theme: events not driven by an inbound channel message are not reliably pushed to the channel.
This is distinct from the recently fixed finish_reason: stop + structured tool_calls issue (#88791).
First, I want to sincerely apologize for the flood of issues coming from this account. I think OpenClaw is genuinely brilliant, and I want to help make it even better. Thank you to all the maintainers for your outstanding work — this project is exceptional, and reporting bugs is my way of giving back.
Affected version: openclaw@2026.5.27 (running); code present in current dist bundle
Summary
With agents.defaults.compaction.notifyUser: true, the user is supposed to be told when a context compaction happens. But the notice is delivered only through the active turn streaming block-reply callback onBlockReply. The notice function hard-returns when that callback is absent.
Consequence: any compaction that runs outside an active, inbound-driven streaming reply turn — e.g. a proactive maxHistoryShare-triggered compaction, or a compaction inside an announce/embedded run (subagent-completion auto-announce) — has no wired onBlockReply, so sendCompactionNotice returns immediately. No notice is delivered, none is queued, and there is no retry.
Impact
Environment
Reproduction / observed evidence
Timeline (session bf5ec6e1-..., WhatsApp direct):
The compaction ran with no active inbound streaming turn -> no onBlockReply -> sendCompactionNotice early-returned.
Root cause
The notice is bound to the per-turn streaming callback rather than to the channel/session delivery layer. sendCompactionNotice is only reachable via the three call sites inside the streaming reply path (phase: start | end | incomplete), each guarded by shouldNotifyUserAboutCompaction, and all of them depend on params.opts.onBlockReply being present. Compactions triggered outside that path (proactive maxHistoryShare, embedded/announce runs) have no such callback.
Location (dist bundle): dist/reply-turn-admission-BaGuBaDP.js, function sendCompactionNotice and the three else-if call sites. (Source path inferred: src/agents/.../reply-turn-admission.ts.)
Proposed fix
Decouple the compaction notice from onBlockReply so it can be delivered for any compaction on the session:
Related (separate issue, same family)
In the same session, the assistant reply generated at step 1 (a subagent-completion auto-announce) was itself never delivered to WhatsApp and was not found in delivery-queue/failed. That is the previously known subagent->requester announce-delivery drop — but both share the root theme: events not driven by an inbound channel message are not reliably pushed to the channel.
This is distinct from the recently fixed finish_reason: stop + structured tool_calls issue (#88791).