agent_ui: Fix session equality check for reloading retained threads#53992
Merged
agent_ui: Fix session equality check for reloading retained threads#53992
Conversation
Add three tests for session disassociation ("Session not found" after
reopening a thread):
1. test_open_thread_on_visible_session_does_not_disassociate_it (passes)
Verifies load_agent_thread short-circuits when the session is already
the active view.
2. test_retained_thread_cleanup_does_not_disassociate_reopened_session (passes)
Verifies that eviction + reopen cycle works correctly.
3. test_retained_thread_reset_race_disassociates_session (FAILS - reproduces bug)
A retained ConversationView with a thread_error receives
AgentServersUpdated, calls reset() (state -> Loading), and then
open_thread creates a second ConversationView for the same session
because has_session returns false on the Loading state. When the
retained view is later cleaned up, its on_release -> close_all_sessions
removes the session from the connection, stranding the active view.
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
benbrandt
reviewed
Apr 16, 2026
| let has_session = |cv: &Entity<ConversationView>| -> bool { | ||
| cv.read(cx) | ||
| .active_thread() | ||
| .is_some_and(|tv| tv.read(cx).thread.read(cx).session_id() == &session_id) |
Member
There was a problem hiding this comment.
The issue was Active thread session id could be a subagent or we could be in a loading/error state and the active thread isn't set yet. But we already know the session id, so we sholuld be using that instead
benbrandt
approved these changes
Apr 16, 2026
bennetbo
approved these changes
Apr 16, 2026
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
Member
|
/cherry-pick preview |
github-actions Bot
pushed a commit
that referenced
this pull request
Apr 16, 2026
…53992) ## Summary Adds three tests that exercise session disassociation ("Session not found" after reopening a thread). The third test **fails**, reproducing the bug. ### Root cause A retained `ConversationView` with a `thread_error` receives `AgentServersUpdated`, which triggers `reset()` → `close_all_sessions` → state transitions to `Loading`. When the user then reopens the same session via `open_thread`, `load_agent_thread`'s `has_session` check returns `false` (because the retained view is in `Loading` state, not `Connected`), so a **second** `ConversationView` is created for the same session. Both views' async load tasks complete and both transition to `Connected` with the same session ID. When the retained view is later cleaned up, its `on_release` → `close_all_sessions` removes the session from the connection, leaving the active view stranded with a dead session. ### Tests | Test | Status | What it verifies | |------|--------|-----------------| | `test_open_thread_on_visible_session_does_not_disassociate_it` | ✅ Pass | `load_agent_thread` short-circuits when session is already active | | `test_retained_thread_cleanup_does_not_disassociate_reopened_session` | ✅ Pass | Eviction + reopen cycle works (close-then-reload) | | `test_retained_thread_reset_race_disassociates_session` | ❌ **Fail** | Reproduces the race described above | cc @bennetbo @ConradIrwin Release Notes: - N/A --------- Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com> Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
18 tasks
eholk
pushed a commit
that referenced
this pull request
Apr 16, 2026
…53992) ## Summary Adds three tests that exercise session disassociation ("Session not found" after reopening a thread). The third test **fails**, reproducing the bug. ### Root cause A retained `ConversationView` with a `thread_error` receives `AgentServersUpdated`, which triggers `reset()` → `close_all_sessions` → state transitions to `Loading`. When the user then reopens the same session via `open_thread`, `load_agent_thread`'s `has_session` check returns `false` (because the retained view is in `Loading` state, not `Connected`), so a **second** `ConversationView` is created for the same session. Both views' async load tasks complete and both transition to `Connected` with the same session ID. When the retained view is later cleaned up, its `on_release` → `close_all_sessions` removes the session from the connection, leaving the active view stranded with a dead session. ### Tests | Test | Status | What it verifies | |------|--------|-----------------| | `test_open_thread_on_visible_session_does_not_disassociate_it` | ✅ Pass | `load_agent_thread` short-circuits when session is already active | | `test_retained_thread_cleanup_does_not_disassociate_reopened_session` | ✅ Pass | Eviction + reopen cycle works (close-then-reload) | | `test_retained_thread_reset_race_disassociates_session` | ❌ **Fail** | Reproduces the race described above | cc @bennetbo @ConradIrwin Release Notes: - N/A --------- Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com> Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
eholk
added a commit
that referenced
this pull request
Apr 16, 2026
We're doing another preview release today to get our latest parallel agents features out there. This PR is a rollup of all the changes we need to cherry pick. - [x] 7a26e48 from #54081 - [x] #54066 - [x] #53992 - [x] #54079 - [x] #54057 - [x] #54056 - [x] #54052 - [x] #53999 - [x] #54009 - [x] #53539 (already cherry picked as 25e02cb) - [x] #54070 - [x] #54053 - fix `run_tests.yml`: 67e92b5 - [x] #53979 - [x] #53884 - [x] #54067 - [x] #54014 (already on branch) - [x] #54030 (already on branch) - [x] #54094 Release Notes: - N/A --------- Co-authored-by: Lukas Wirth <me@lukaswirth.dev> Co-authored-by: Bennet Bo Fenner <bennet@zed.dev> Co-authored-by: Nathan Sobo <nathan@zed.dev> Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com> Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de> Co-authored-by: Danilo Leal <67129314+danilo-leal@users.noreply.github.com> Co-authored-by: Neel <neel@zed.dev> Co-authored-by: Richard Feldman <richard@zed.dev>
G36maid
pushed a commit
to G36maid/zed
that referenced
this pull request
Apr 29, 2026
…ed-industries#53992) ## Summary Adds three tests that exercise session disassociation ("Session not found" after reopening a thread). The third test **fails**, reproducing the bug. ### Root cause A retained `ConversationView` with a `thread_error` receives `AgentServersUpdated`, which triggers `reset()` → `close_all_sessions` → state transitions to `Loading`. When the user then reopens the same session via `open_thread`, `load_agent_thread`'s `has_session` check returns `false` (because the retained view is in `Loading` state, not `Connected`), so a **second** `ConversationView` is created for the same session. Both views' async load tasks complete and both transition to `Connected` with the same session ID. When the retained view is later cleaned up, its `on_release` → `close_all_sessions` removes the session from the connection, leaving the active view stranded with a dead session. ### Tests | Test | Status | What it verifies | |------|--------|-----------------| | `test_open_thread_on_visible_session_does_not_disassociate_it` | ✅ Pass | `load_agent_thread` short-circuits when session is already active | | `test_retained_thread_cleanup_does_not_disassociate_reopened_session` | ✅ Pass | Eviction + reopen cycle works (close-then-reload) | | `test_retained_thread_reset_race_disassociates_session` | ❌ **Fail** | Reproduces the race described above | cc @bennetbo @ConradIrwin Release Notes: - N/A --------- Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com> Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
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
Adds three tests that exercise session disassociation ("Session not found" after reopening a thread). The third test fails, reproducing the bug.
Root cause
A retained
ConversationViewwith athread_errorreceivesAgentServersUpdated, which triggersreset()→close_all_sessions→ state transitions toLoading. When the user then reopens the same session viaopen_thread,load_agent_thread'shas_sessioncheck returnsfalse(because the retained view is inLoadingstate, notConnected), so a secondConversationViewis created for the same session. Both views' async load tasks complete and both transition toConnectedwith the same session ID. When the retained view is later cleaned up, itson_release→close_all_sessionsremoves the session from the connection, leaving the active view stranded with a dead session.Tests
test_open_thread_on_visible_session_does_not_disassociate_itload_agent_threadshort-circuits when session is already activetest_retained_thread_cleanup_does_not_disassociate_reopened_sessiontest_retained_thread_reset_race_disassociates_sessioncc @bennetbo @ConradIrwin
Release Notes: