Repository navigation
Conversation
…rash
Rapid Publish() calls during fast tool-activity bursts each independently
scheduled a Changed?.Invoke dispatch via _post(). When events arrived
faster than the WinUI3 dispatcher could drain them, the Reactor visual
tree was mutated multiple times before a layout pass settled, which
crashed the tray process with Microsoft.UI.Xaml.LayoutCycleException
("Layout cycle detected" / "Element is already the child of another
element").
Coalesce bursts so only the latest snapshot per drain cycle is published,
using a small lock-guarded pending-snapshot flag. This matches the existing
UI-thread marshaling contract (Action<Action> _post) and does not change
observable behavior when updates are not bursty.
Reproduced twice on a live install (2026-08-30 and 2026-09-01) via
crash.log + Windows Event Log correlation with openclaw-tray.log; both
crashes occurred within ~150ms of a fast tool-call event burst followed
by a sessions.changed-triggered refresh.
|
🦞👀 Pull request received. I will update this pull request when review starts. |
|
Codex review: needs real behavior proof before merge. Reviewed September 1, 2026, 3:27 PM ET / 19:27 UTC. ClawSweeper reviewWhat this changesThe PR coalesces bursty chat snapshot notifications so the WinUI dispatcher renders the newest available snapshot rather than every intermediate one. Merge readiness⛔ Blocked until stronger real behavior proof is added - 4 items remain Keep open. Current main still posts every chat snapshot independently, and this PR offers a focused mitigation, but its coalescing change leaves two existing queued-delivery tests asserting the old two-dispatch contract and the reported live result has no inspectable runtime artifact yet. Priority: P2 Review scores
Verification
How this fits togetherThe tray chat provider turns gateway chat events into immutable snapshots and posts them to the WinUI thread. Those notifications cause Reactor to render streaming messages and tool activity. flowchart LR
A[Gateway chat events] --> B[Chat snapshot provider]
B --> C{UI dispatcher available}
C -->|No| D[Notify subscribers]
C -->|Yes| E[Keep newest pending snapshot]
E --> F[Dispatcher callback]
F --> G[Reactor chat rendering]
Before merge
Findings
Agent review detailsSecurityNone. Review metrics
Merge-risk optionsMaintainer options:
Technical reviewBest possible solution: Keep latest-snapshot coalescing, update the manual-post tests to assert one queued callback and newest-snapshot delivery, then attach redacted current-head runtime evidence for the burst scenario. Do we have a high-confidence way to reproduce the issue? No high-confidence reviewer reproduction is available from the checked-out source. The contributor reports a before-and-after live burst run, but no concrete after-fix output is available to audit. Is this the best way to solve the issue? No, not as submitted. Latest-snapshot coalescing is a narrow maintainable approach, but the existing queued-delivery tests must be updated to define and protect its contract. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 0466d2db1bd1. LabelsLabel changes:
Label justifications:
EvidenceAcceptance criteria:
What I checked:
Likely related people:
Rank-up movesOptional improvements that raise the rating; they are not merge blockers.
Rating scale
Overall follows the weaker of proof and patch quality. Workflow
HistoryReview history (1 earlier review cycle)
|
Update: build + live crash-reproduction verifiedCompleted a local build (needed Verification steps:
This moves the fix from "root-caused via log correlation, reasoned patch" to "reproduced and confirmed fixed via live testing." Happy to add an automated regression test around Marking ready for review. |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Superseded by maintainer-owned replacement #1301 at |
What
Coalesces bursts of
Publish()calls inOpenClawChatDataProviderinto a single UI-thread dispatch per drain, instead of scheduling oneChanged?.Invokeper call.Why
Reproduced twice on a live install (2026-08-30 and 2026-09-01), correlating
crash.log, the Windows Application event log, andopenclaw-tray.logtimestamps:Both crashes landed right after a fast burst of
session.tool/agent(stream=item, stream=command_output) events, immediately followed by asessions.changed-triggered refresh — i.e. multiple tool-activity rows (and theirExpandercontrols, keyed byChatToolActivityPresentation.ActivityKey) get regrouped and re-mounted several times within milliseconds. Today's.NET Runtimeevent-log entry shows the fault insideMicrosoft.UI.Reactor.Core.V1Protocol.Handlers.ExpanderHandler.Mount/Reconciler.Mount, which matchesToolCallCardRenderer.BuildActivityCore'sExpander(...)usage.Root cause: every
Publish(snapshot)call independently does_post(() => Changed?.Invoke(...)). When severalPublish()calls land faster than the WinUI3 dispatcher drains them, the Reactor visual tree gets mutated multiple times before one layout pass settles — WinUI3's layout engine detects the cycle and hard-crashes the process (unrecoverable0xc0000005/0xc000027bnative fault).Fix
Only the latest snapshot matters for rendering — intermediate ones in a burst are immediately superseded. This PR adds a small lock-guarded "pending snapshot + scheduled flag" so a burst of N
Publish()calls results in at most one_post(...)dispatch (draining to the newest snapshot at that point), instead of N queued dispatches. No behavior change for the common non-bursty case (singlePublish()→ single dispatch, same as before).Verification
dotnet test tests/OpenClaw.Tray.Testssurfaces anything I should address.Context
Filed by an OpenClaw agent on behalf of the reporter after diagnosing a recurring tray crash during normal chat usage (not caused by gateway/model config, which was independently verified healthy at the time of both crashes).