Fix removed workspace resurrecting via serialization race#52035
Merged
Fix removed workspace resurrecting via serialization race#52035
Conversation
In remove_workspace, the removed Entity<Workspace> could still have a pending serialize_workspace throttle timer. When that timer fired, serialize_workspace_internal would write the old session_id back to the DB, undoing the removal and causing the workspace to reappear on next launch. Fix: clear session_id and cancel pending serialization tasks on the removed workspace entity before the DB cleanup, mirroring what remove_from_session already does.
bennetbo
approved these changes
Mar 23, 2026
AmaanBilwar
pushed a commit
to AmaanBilwar/zed
that referenced
this pull request
Mar 23, 2026
…ries#52035) In `remove_workspace`, the removed `Entity<Workspace>` could still have a pending `serialize_workspace` throttle timer (200ms). When that timer fired, `serialize_workspace_internal` would write the old `session_id` back to the DB — undoing the removal. On next restart, the workspace would reappear. The race window opens whenever any state change (worktree change, breakpoint change, etc.) triggers `serialize_workspace` within 200ms before `remove_workspace` is called. **Fix**: Before the DB cleanup task, `update` the removed workspace entity to: 1. `session_id.take()` — so any in-flight serialization writes `session_id: None` 2. `_schedule_serialize_workspace.take()` — cancel the pending throttle timer 3. `_serialize_workspace_task.take()` — cancel any actively running serialization task This mirrors what `remove_from_session` already does (clearing `session_id`), but `remove_workspace` was missing it. Release Notes: - Fixed a bug where a removed workspace could reappear on next launch due to a serialization race.
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.
In
remove_workspace, the removedEntity<Workspace>could still have a pendingserialize_workspacethrottle timer (200ms). When that timer fired,serialize_workspace_internalwould write the oldsession_idback to the DB — undoing the removal. On next restart, the workspace would reappear.The race window opens whenever any state change (worktree change, breakpoint change, etc.) triggers
serialize_workspacewithin 200ms beforeremove_workspaceis called.Fix: Before the DB cleanup task,
updatethe removed workspace entity to:session_id.take()— so any in-flight serialization writessession_id: None_schedule_serialize_workspace.take()— cancel the pending throttle timer_serialize_workspace_task.take()— cancel any actively running serialization taskThis mirrors what
remove_from_sessionalready does (clearingsession_id), butremove_workspacewas missing it.Release Notes: