Fix thread detachment when re-opening live session via new sidebar - #52
Merged
Conversation
After PRs #42/#43 landed the new agents sidebar, clicking the currently-open thread in the sidebar caused the panel to detach from the live Entity<AcpThread>: Zed's panel stopped updating but Helix kept receiving message_added/message_completed events for the same session. Single-thread, single-click was enough to trigger it. Root cause: two parallel dedup paths in agent_panel.rs use different identity checks. notify_thread_display (Helix bring-up) compares Entity<AcpThread> references; panel.load_agent_thread (UI clicks) compares acp::SessionId. When the session-id check missed, external_thread issued a duplicate connection.load_session(), producing a fresh entity Y. Helix's WebSocket subscription stayed on the original X (events kept flowing) but the panel rebound to Y (silent) — same split-brain shape as d7be64f (restart variant), different trigger. Fix: add an #[cfg(feature = "external_websocket_sync")]-gated guard at the top of load_agent_thread, before the existing has_session block. Look up external_websocket_sync::get_thread(session_id); if a live entity exists, do entity-id matching against active and retained CVs; if no view observes it, wrap it via ConversationView::from_existing_thread (the same path notify_thread_display uses). Falls through to the unchanged upstream logic when no live entity exists. Also documents this in portingguide.md as Critical Fix #11 with rebase instructions. Spec task: 001913_after-merging-latest-2 Release Notes: - Fixed thread becoming detached when clicking the currently-open thread in the new agents sidebar (Helix mode). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Spec-Ref: helix-specs@77d9c813c:001913_after-merging-latest-2
…merging-latest-2 Spec-Ref: helix-specs@21bb2539d:001913_after-merging-latest-2
lukemarsden
added a commit
to helixml/helix
that referenced
this pull request
May 8, 2026
Pulls in the entity-identity guard at the top of agent_panel.rs::load_agent_thread that fixes the "thread becomes detached when clicking the currently-open thread in the new agents sidebar" bug. See helix/design/2026-05-06-acp-thread-entity-routing-on-sidebar-click.md for the full writeup. Spec task: 001913_after-merging-latest-2 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Spec-Ref: helix-specs@31416ab8e:001913_after-merging-latest-2
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
After the two upstream-merge PRs (#42 / #43) landed the new agents sidebar, clicking the currently-open thread in the sidebar caused the panel to "detach" from the live
Entity<AcpThread>: Zed's panel stopped updating but Helix kept receivingmessage_added/message_completedevents for the same session. Single-thread, single-click was enough to trigger it — noThreadSwitcher, no restart.Root cause: two parallel dedup paths in
agent_panel.rsuse different identity checks.notify_thread_display(Helix bring-up) comparesEntity<AcpThread>references;panel.load_agent_thread(UI clicks) comparesacp::SessionId. When the session-id check missed,external_threadissued a duplicateconnection.load_session(), producing a fresh entity Y. Helix's WebSocket subscription stayed on the original X (events kept flowing) but the panel rebound to Y (silent) — the same split-brain shape asd7be64fad1(restart variant), different trigger.Fix
Adds an
#[cfg(feature = "external_websocket_sync")]-gated guard at the top ofpub fn load_agent_threadincrates/agent_ui/src/agent_panel.rs, before the existinghas_sessionblock:external_websocket_sync::get_thread(session_id).ConversationView::from_existing_thread(…)(same pathnotify_thread_displayuses).The new code is purely additive in front of the existing function body. Outside the Helix feature, behaviour is unchanged.
Changes
crates/agent_ui/src/agent_panel.rs— entity-identity guard at the top ofload_agent_thread.portingguide.md— Critical Fix Upstream merge 2026 02 26 #11 documenting the guard, its rebase requirements, and its relationship to the previousunregister_thread_if_matchesfix.Notes
run_docker_e2e.shsetup. Build was attempted via./stack build-zed dev(zed-builder docker image); status noted in the spec task. Reviewer to run the manual repro and the E2E script before merging.root_session_idNone/stale, session-id mismatch between paths,BaseView::Uninitializedat click time). The entity-id guard short-circuits all three without needing to confirm which is hit. If a follow-up investigation finds a specific root cause, a smaller upstream fix is also possible — but this guard is the safe Helix-side floor.Release Notes:
🔗 Open in Helix
📋 Spec:
🚀 Built with Helix