sessions: persist closed chats across session switch#323429
Merged
Merged
Conversation
Closed (hidden) chats reappeared when switching the visible session away and back, because the closed-chat set was only snapshotted at save time and the session's wrapper (and its in-memory closed set) is disposed on switch. Persist the set deterministically in closeChat/openChat instead of deriving it reactively from closedChats (which intersects with loaded chats), so it survives switches and reloads regardless of load timing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
📬 CODENOTIFYThe following users are being notified based on files changed in this PR: @lszomoruMatched files:
|
Contributor
|
This PR will be automatically cherry-picked to |
Contributor
There was a problem hiding this comment.
Pull request overview
This pull request fixes a state-loss bug in the Agents window where closed (hidden) chats could reappear after switching away from a session and back, by persisting the closed-chat set in SessionsService so it survives VisibleSession wrapper disposal and restores correctly on reopen (and across reloads when the session is persisted).
Changes:
- Persist closed/open chat state deterministically on
closeChat/openChatvia_setChatClosedState, independent of loaded chats / autorun timing. - Adjust save-time session-state snapshotting to prefer the explicitly maintained closed-chat set.
- Add a dedicated “closed chats persistence” test suite covering the repro (including closing the middle of three chats) and update
SESSIONS.mddocumentation.
Show a summary per file
| File | Description |
|---|---|
| src/vs/sessions/services/sessions/browser/sessionsService.ts | Persist closed-chat URIs into _sessionStates on close/open and prefer that set when snapshotting state for storage. |
| src/vs/sessions/services/sessions/test/browser/sessionsManagementService.test.ts | Adds regression tests proving closed chats remain closed across session switches and reopen operations. |
| src/vs/sessions/SESSIONS.md | Documents how per-session closed-chat state is maintained and why it must be updated synchronously on close/open. |
Review details
- Files reviewed: 3/3 changed files
- Comments generated: 0
- Review effort level: Low
lszomoru
approved these changes
Jun 29, 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.
What
Closed (hidden) chats in the Agents window reappeared in the tab strip when you closed a chat, switched the visible session to another session, and switched back. This persists the closed-chat state so closed tabs stay hidden across session switches (and reloads), with only one session visible at a time.
Why
Closed-chat state lived in the VisibleSession wrapper's in-memory set and was only written to storage at save time (onWillSaveState) for visible sessions. Switching the session out of the grid disposes its wrapper before any flush, and reopening rebuilt it from stale state — so the closed set was lost. A first attempt persisted the set reactively from the closedChats observable, but that derivation is closedURIs intersected with loadedChats, so it depended on chats being loaded and on autorun timing, and still failed when a session's chats were re-resolving on switch-back.
How
Validated: tsgo typecheck, eslint, layers check, and the new tests pass; tests fail without the fix.