fix(web): drop SSE plan_update/approval_needed events without thread_id - #2986
Merged
Merged
Conversation
The plan_update and approval_needed handlers used short-circuit guards (`data.thread_id && !isCurrentThread(...)` and `!hasThread || isCurrentThread(...)`) that fell through to render in the current view when thread_id was missing. When a backend tool path emitted PlanUpdate with ctx.conversation_id = None (mission/routine execution), the plan checklist appeared in whatever conversation the user had switched to. Use `isCurrentThread(data.thread_id)` directly — it returns false for falsy input, matching the strict convention every other thread-scoped handler (response, stream_chunk, tool_started, ...) already uses. Also guard approval_needed's else branch with `data.thread_id` so a null value no longer leaks into the unreadThreads Map as a key. [skip-regression-check] frontend static-JS only; no JS test infrastructure in repo, equivalent to src/channels/web/static/ exempt.
Contributor
There was a problem hiding this comment.
Code Review
This pull request refactors the Server-Sent Events (SSE) event listeners in sse.js to simplify conditional logic. The approval_needed listener was updated to remove redundant variables and clarify the handling of background thread updates, while the plan_update listener was streamlined by removing an unnecessary check for data.thread_id. I have no feedback to provide as there were no review comments to evaluate.
serrrfirat
enabled auto-merge (squash)
April 28, 2026 05:48
serrrfirat
disabled auto-merge
April 28, 2026 05:48
Merged
This was referenced May 7, 2026
Closed
Closed
Merged
theredspoon
pushed a commit
to theredspoon/ironclaw
that referenced
this pull request
Jun 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
plan_update,approval_needed) used short-circuit guards that treated missingthread_idas "applies to current view".isCurrentThread(data.thread_id)filtering — matching the convention every other thread-scoped handler insse.js(response,stream_chunk,tool_started, …) already uses.approval_needed's else branch ondata.thread_idso a null value no longer pollutes theunreadThreadsMap.Root cause
PlanUpdateTool::executeatsrc/tools/builtin/plan.rs:143emits:The old frontend guard:
if (data.thread_id && !isCurrentThread(data.thread_id)) return;
short-circuits on the falsy thread_id and falls through to renderPlanChecklist(data), which renders into the currently-displayed conversation. Same shape on approval_needed via forCurrentThread = !hasThread || isCurrentThread(...).
The fix is at the correct boundary: isCurrentThread(null) === false per chat.js:1-5, so !isCurrentThread(data.thread_id) filters thread_id-less events out instead of routing them to the active view.
Change Type
Linked Issue
fixes #2833
Validation
cargo fmt --all -- --checkcargo clippy --all --benches --tests --examples --all-features -- -D warningscargo buildcargo test --features integrationif database-backed or integration behavior changedreview-prorpr-shepherd --fixwas run before requesting reviewSecurity Impact
Database Impact
Blast Radius
Rollback Plan
Review Follow-Through
Review track: