Skip to content

workspace: Fix opening closed projects randomly when Zed restarts#50961

Merged
ConradIrwin merged 5 commits intozed-industries:mainfrom
AmaanBilwar:fix/opening-closed-projects-randomly
Mar 12, 2026
Merged

workspace: Fix opening closed projects randomly when Zed restarts#50961
ConradIrwin merged 5 commits intozed-industries:mainfrom
AmaanBilwar:fix/opening-closed-projects-randomly

Conversation

@AmaanBilwar
Copy link
Copy Markdown
Contributor

@AmaanBilwar AmaanBilwar commented Mar 6, 2026

Closes #49854

Before you mark this PR as ready for review, make sure that you have:

  • Added a solid test coverage and/or screenshots from doing manual testing
  • Done a self-review taking into account security and performance aspects
  • No UI changes

Video for the fix:
in the video i open a project -> close the project -> quit out of zed -> reopen zed -> zed opens to an empty workspace which was not the case before

projectfix.mp4

Release Notes:

  • Fixed closed projects re-opening erroneously

@cla-bot cla-bot bot added the cla-signed The user has signed the Contributor License Agreement label Mar 6, 2026
@maxdeviant maxdeviant changed the title workspace: Fix opening closed projects randomly when zed restarts workspace: Fix opening closed projects randomly when Zed restarts Mar 6, 2026
@ConradIrwin
Copy link
Copy Markdown
Member

Seems like this probably works to fix it, but before we commit it I'd like to understand why the workspace session id is being used in the wrong way deeper in the. code.

@AmaanBilwar
Copy link
Copy Markdown
Contributor Author

@ConradIrwin

when a user quits zed:

  • prepare_to_close(quit) is called (workspace.rs:2911)
  • condition close_intent != CloseIntent::Quit is false
  • remove_from_session is skipped, next time uopen zed session id stays in db, queries it & restores the workspace, This is the correct behavior

when we close a window

  • prepare_to_close(CloseWindow) is called (workspace.rs:2911`)
  • condition close_intent != CloseIntent::Quit is true
  • remove_from_session is called -> sets session_id to NULL in db
    next launch zed uses that session+id doesnt find the row doesnt restore it

when we open a diff project in same window

  • open_project calls prepare_to_close(ReplaceWindow) (multi_workspace.rs:677)
  • same logic repalce window != quit so remove_from_session is called
  • old project's session_id is cleared in db
    new project gets its own db row with valid session_id
    c

the bug when we close proj

  • CloseProject hadnler runs (zed.rs:1079)
  • it calls open_new directly which creates a fresh empty workspace
  • multi_workspace.activate() replaces old workspace entity (multi_workspace.rs:313)
  • old entity now dropped on drop, the on_release handler (workspace.rs:1669-1676) but it only removes reference from an inmemory list nothing withthe database
  • the old project's db row still has sesssion id set
  • next launch zed queries that session id, finds row, restores the closed proj.

my fix

basically adds 2 lines before open_new:

let remove_task = workspace.remove_from_session(window, cx); // clear session_id in db 
remove_task.await; // wait  for db write

@AmaanBilwar
Copy link
Copy Markdown
Contributor Author

AmaanBilwar commented Mar 10, 2026

tldr : we never call remove_from_session or prepare_to_close

open_project is a good example of doing it correctly? afaik

cx.spawn_in(window, async move |_this, cx| {
    let should_continue = workspace
        .update_in(cx, |workspace, window, cx| {
            workspace.prepare_to_close(crate::CloseIntent::ReplaceWindow, window, cx)  // <-- cleans up DB
        })?
        .await?;
    if should_continue {
        workspace
            .update_in(cx, |workspace, window, cx| {
                workspace.open_workspace_for_paths(true, paths, window, cx)
            })?
            .await
    } else {
        Ok(())
    }
})

hope this helps a lil bit :))

@ConradIrwin
Copy link
Copy Markdown
Member

Interesting. Should we call prepare_to_close instead of remove_from_session? It looks like that method also checks for active calls etc.

call remove_from_session to immediately remove session_id from memory,
spawns task that awaits db write, calls open_new to replace window with
empty workssapce
uses `prepare_to_close(CloseIntent::ReplaceWindow)` on the current
worksapce, this clears session_id, serializes unsaved buffer state adn
handles active call cleanup.

matches the pattern we have in `MultiWorkspace::open_project` in
`multi_workspace.rs`
@AmaanBilwar
Copy link
Copy Markdown
Contributor Author

AmaanBilwar commented Mar 12, 2026

Interesting. Should we call prepare_to_close instead of remove_from_session? It looks like that method also checks for active calls etc.

@ConradIrwin
i just read into it and this is def better we can also save unsaved files on top of looking at active calls. made the changes

@AmaanBilwar AmaanBilwar force-pushed the fix/opening-closed-projects-randomly branch from ed6d11c to 95d488d Compare March 12, 2026 18:57
@ConradIrwin
Copy link
Copy Markdown
Member

THanks!

@ConradIrwin ConradIrwin enabled auto-merge (squash) March 12, 2026 22:38
@ConradIrwin ConradIrwin merged commit cc09611 into zed-industries:main Mar 12, 2026
28 checks passed
tommyming pushed a commit to tommyming/zed that referenced this pull request Mar 13, 2026
…d-industries#50961)

Closes zed-industries#49854 

Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [x] No UI changes

Video for the fix: 
in the video i open a project -> close the project -> quit out of zed ->
reopen zed -> zed opens to an empty workspace which was not the case
before


https://github.com/user-attachments/assets/1afb44a1-932b-4dab-8228-9d9d65750b6e



Release Notes:
 - Fixed closed projects re-opening erroneously
@esthertrapadoux esthertrapadoux moved this to Shipped by the Guild in Zed Guild - The Board Mar 13, 2026
@zelenenka zelenenka added the guild Pull requests by someone in Zed Guild. NOTE: the label application is automated via github actions label Mar 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed The user has signed the Contributor License Agreement guild Pull requests by someone in Zed Guild. NOTE: the label application is automated via github actions

Projects

Status: Shipped by the Guild

Development

Successfully merging this pull request may close these issues.

Zed opens previously open projects randomly

4 participants