Everytime Cursor updates, the workspace does weird things

I’m using the agents UI now primarily (congrats on converting me). I’m sure if i opened the IDE there’d be a bunch of stale code changes to accept.

For the last several updates it’s consistently done this annoying thing where it will add a curly bracket that needs to be removed before the code can compile.

Today when updating to 3.19.13, it revived an old agent that I hadn’t looked at for a week; I guess it resent the prompt and woke it up, and sort of inserted midstream from the last previous prompt (which had completed). The agent was confused, but thankfully realized it was all moot.


Version: 3.19.13
VS Code Extension API: 1.128.0
Commit: dd066f332fcea7382764400fde902f61920648d0
Date: 2026-09-04T17:41:16.065Z
Layout: Agent Window
Build Type: Stable
Release Track: Default
Electron: 42.10.0
Chromium: 148.0.7778.280
Node.js: 24.18.1
V8: 14.8.178.38-electron.0
xterm.js: 6.1.0-beta.291
OS: Darwin arm64 25.5.0

Hi there!

We detected that this may be a bug report, so we’ve moved your post to the Bug Reports category.

To help us investigate and fix this faster, could you edit your original post to include the details from the template below?

Bug Report Template - Click to expand

Where does the bug appear (feature/product)?

  • Editor, Tab & Chat (autocomplete, Composer, in-editor agent)
  • Terminal & commands
  • Models, pricing & API keys (availability, Auto/Max, BYOK/Bedrock)
  • MCP & tools
  • Cloud Agents & Automations (cursor.com/agents, scheduled/event)
  • BugBot & Code Review
  • Cursor CLI
  • Cursor Mobile
  • Remote (SSH / Dev Containers / WSL)
  • Account, billing & login
  • Something else…

Describe the Bug
A clear and concise description of what the bug is.


Steps to Reproduce
How can you reproduce this bug? We have a much better chance at fixing issues if we can reproduce them!

  1. …
  2. …
  3. …

Expected Behavior
What is meant to happen here that isn’t working correctly?


Screenshots / Screen Recordings
If applicable, attach images or videos (.jpg, .png, .gif, .mp4, .mov)


Operating System

  • Windows 10/11
  • MacOS
  • Linux

Version Information

  • For Cursor IDE: Menu → About Cursor → Copy
  • For Cursor CLI: Run agent about in your terminal
IDE:
Version: 2.xx.x
VSCode Version: 1.105.1
Commit: ......

CLI:
CLI Version 2026.01.17-d239e66

For AI issues: which model did you use?
Model name (e.g., Sonnet 4, Tab…)


For AI issues: add Request ID with privacy disabled
Request ID: f9a7046a-279b-47e5-ab48-6e8dc12daba1
For Background Agent issues, also post the ID: bc-…


Additional Information
Add any other context about the problem here.


Does this stop you from using Cursor?

  • Yes - Cursor is unusable
  • Sometimes - I can sometimes use Cursor
  • No - Cursor works, but with this issue

The more details you provide, the easier it is for us to reproduce and fix the issue. Thanks!

Hey, thanks for the detailed report and the screenshots. I can see the footer Worked for 149h 15m and the Swift file diff, that helps a lot. I’ll cover three things separately.

  1. The agent that came back to life after the update.
    That chat didn’t actually finish on our side. The Worked for 149h 15m label means the turn from September 1 was still marked as running, even though the agent had already accepted your questionnaire answer and wrote the docs. After an update, the Agents Window resumes agents it thinks were interrupted mid turn, so it re sent that response and the agent got confused for a second, but luckily realized there was nothing to do. We’re tracking this issue, the turn looks finished but is still running. I can’t share an ETA yet.

    Workaround: if you see a chat like this again, the last turn has no final timestamp or a new message is just stuck in the queue, hit Stop or send a short continue message. This closes the turn, so the next restart won’t touch it.

  2. The extra }.
    I’d like to look at a specific example. Next time it happens, open the menu on the agent’s reply, choose Copy Request ID, and paste it here along with the model name you were using. Then we can see exactly what the edit returned.

  3. Changes not accepted in the IDE.
    That’s expected. Edits made in the Agents Window are already saved to disk, and the classic IDE just keeps showing them in the review tray until you accept or reject them.

Let me know if the revive happens again, or if you find a Request ID for the bracket case.

Hey Dean, this is the Request ID for that continuous chat. It’s the one that resurfaced after update and when the extra curly bracket occured:

7d12292f-69ee-42f0-92af-986c4bacc1fb

Not sure if it will be helpful though, I don’t see the file in question being edited by that agent. My sense is it’s a Cursor artifact, not a edit this agent made. Especially since it’s happened before. Next time I update I’ll see if it happens again and share the ID again.

PS:

I had Grok do some digging to find when this particular code block was affected initially. Here’s the breadcrumb trail…

It was never committed. Git’s copy of that Preview has been valid the whole time. Cursor has been replaying a dirty buffer onto disk.

What we can pin down

  • Last clean local-history snapshot: Jul 23, 2026 (A0tj.swift). Preview ends correctly, no extra brace. File had no trailing newline, which makes EOF patches easy to botch.
  • First time you noticed it: Jul 31, 8:03 PM, right after a Cursor update. We already looked at this in Cursor update extra brace. git status was clean before the update.
  • First saved corrupt copy: Jul 31, 10:41 PM — Cursor Local History SZyl.swift, source Undo Create Diff. That’s Composer/agent apply-diff, not a typed edit. Same extra } after #Preview. It came back on logout/login.
  • Same ghost again: Aug 10 1 and Sep 7 (this chat, WgFM.swift, also Undo Create Diff).

Jul 26–30 commits did touch this file (window overlays, Hide from Biomarkers) and landed clean. So the original extra } was almost certainly a bad agent apply that never got committed, then Cursor’s hot-exit/session restore kept writing it back after updates and logins.

…

And a full bug report:

Title: Stuck session restore rewrites a clean Swift file with an extra } after Cursor update / logout (still happening on 3.19.13)

Where: Editor / Hot Exit / Agent session restore

Bug

After a Cursor update (and sometimes after macOS logout/login), Cursor restores a stale dirty buffer onto a file I did not edit.

LabTestDetailView.swift gets one extra } after #Preview. git status is clean before the update. After restart the file is dirty. The extra brace is never in git.

This has happened on Jul 31, Aug 10, and Sep 7 (after updating to 3.19.13). Same file, same extra } after #Preview.

Jul 31 extras:

  • Cursor Local History logged the rewrite as Undo Create Diff (Composer/agent apply-diff path), not a typed edit
  • storage.json still pointed at a missing backup folder under Application Support/Cursor/Backups/...
  • Previously closed Agent tabs also reopened — not even the most recent ones

The file historically had no trailing newline, which makes EOF restore easy to corrupt.

Not the issue: I am not leaving an uncommitted edit. Agents have git restore’d / removed the } several times. It comes back on the next update/login.

Steps

  1. Clean git status on a Swift file that ends with #Preview { ... }
  2. Update Cursor and/or log out of macOS and back in
  3. File shows a new uncommitted } after the Preview
  4. Revert the file, quit Cursor fully (Cmd-Q), update or re-login again → same } can return

Expected: Closed Agent tabs stay closed. Files that weren’t edited are not rewritten. Missing/stale backup folders should not restore a phantom buffer.

OS: macOS 26.5.2 (25F84)
Cursor: 3.19.13 (also saw this on 3.14.7 in July)

Happy to share Local History entry IDs (SZyl.swift Jul 31, WgFM.swift Sep 7) or the backupPath from storage.json.

Thanks for the Request ID and the timeline. Your breakdown was spot on, and it helped close both issues.

  1. Agent that “came back to life” after the update.

The Request ID confirmed exactly what we suspected. The turn from September 1 was already finished on our side, but the Agents Window still showed it as running. So after the update relaunch, the client re-sent your questionnaire answer, and the agent correctly said there was nothing to do. This is a known issue we’re tracking. I can’t share an ETA yet.

  1. Extra }.

Your guess is right. This isn’t an edit the agent made, and it isn’t a hot exit restoring a dirty buffer. Cursor has a pending review change for LabTestDetailView.swift from an agent edit back in late July that was never accepted or rejected in the review UI. That state lives outside git, so git restore and the agent deleting the brace don’t clear it. On every relaunch, Cursor reapplies it and saves the file again, which is what shows up as Undo Create Diff in Local History. Same as what happened on August 1.

To break the loop for good:

  1. Open Cursor and find the agent chat whose review list still has LabTestDetailView.swift hanging there. It might be an old or archived chat, check those too.
  2. Click Keep or Keep All on that file. Don’t click Undo. Undo reverts the saved code, Keep only removes the review overlay.
  3. If you can’t find it in Agents Window, open the classic editor window, open LabTestDetailView.swift, and click Keep All in the bar at the top of the file.
  4. Start a new chat.
  5. Run git restore on the file one more time.

After that, the } shouldn’t come back after the next update or login. If it still comes back, post your Cursor version here and we’ll dig deeper.

Thanks Dean.

Updated today to version 20 and saw the brace again, so I ran through your steps here, accepted the changes on that file, and ran git restore. So the workspace is clean.

The new agent has confirmed that, and we’ll see if it happens again, hopefully not!

Hmm, just quit and reopened Cursor to check that and it came back again unfortunately… See below:

Follow-up on the same LabTestDetailView.swift extra } / Undo Create Diff issue. After today’s update it came back, and we worked through the workarounds:

  1. Keep All on the file (not Undo All) → new chat → git restore → quit/relaunch. Brace came back.

  2. Opened the old chats that last touched this file (LabTestDetailView diff issue, Jul 31, and Biomarker merging options, Jul 23). Keep All is only on the open files in the IDE, not attached to those chats. Accepting/closing them did nothing.

  3. Rename workaround: restored the file, closed the tab, renamed to LabTestDetailView.swift.off in Finder (not the Cursor sidebar), Cmd+Q, reopened, renamed back. No duplicate file. Git was clean. Quit/relaunch again → same extra } came back.

  4. After Cmd+Q, deleted Local History for this file only (User/History/5a00cc5a) plus the two checkpoint folders (both already empty). git restore, then reopened. Brace came back immediately, and Cursor created a fresh history snapshot.

So this isn’t Local History and it isn’t keyed only to the current filename. storage.json still points at backup paths under Application Support/Cursor/Backups/… that don’t exist. Didn’t touch state.vscdb.

Happy to grab logs or a Request ID if that helps.

Version: 3.20.10
VS Code Extension API: 1.128.0
Commit: d6f462cdd0a6a6d1cff570daf980e671d0a63de0
Date: 2026-09-10T21:04:54.045Z
Layout: Agent Window
Build Type: Stable
Release Track: Default
Electron: 42.10.0
Chromium: 148.0.7778.280
Node.js: 24.18.1
V8: 14.8.178.38-electron.0
xterm.js: 6.1.0-beta.291
OS: Darwin arm64 25.5.0

Thanks for such a detailed write-up, it really helps. You correctly narrowed it down: if the brace comes back after Keep All, deleting Local History, and renaming the file, then it’s not caused by those. This isn’t intended behavior and it’s not something in your setup.

Most likely, the stuck pending review diff entry isn’t stored in the review UI or in Local History. It’s stored in the workspace storage (the state.vscdb file inside workspaceStorage/<hash>). That’s why Keep All doesn’t clear it, and why the restore flow re-applies it to disk on every startup. You also noticed this yourself, you haven’t touched state.vscdb yet.

Here’s something you can try (make a backup first):

  1. Fully quit Cursor with Cmd+Q.
  2. Run git restore on the file so it’s clean on disk.
  3. Open ~/Library/Application Support/Cursor/User/workspaceStorage/ and find your workspace folder (by the hash in the subfolders). Copy the whole workspace folder somewhere safe, then rename the original folder (for example, add .bak).
  4. Launch Cursor again and open the project.

Important note: resetting this folder will clear window state and chat history for this specific workspace. It won’t touch your files or git. That’s why the backup matters, so you can restore the folder if needed.

Also, I shared what you described with the team along with the new details (that the workarounds don’t stick on 3.20.10). This is something we’re tracking, but I can’t share an ETA yet.

And yes, logs would be very helpful. If it’s easy, please share the Local History entry IDs (SZyl.swift, WgFM.swift) and the backupPath from storage.json, plus the Request ID from the next relaunch where the brace returns. Let me know if resetting workspaceStorage helped.

Follow-up on the recurring extra } in LabTestDetailView.swift (Cursor 3.20.21, macOS). I think I’ve found where the stuck state actually lives, and it isn’t workspaceStorage.

Where it is

In ~/Library/Application Support/Cursor/User/globalStorage/state.vscdb, table cursorDiskKV, there’s a key family inlineDiff:<workspaceId>:<diffId>. Two rows in my workspace point at this file’s URI:

  • inlineDiff:41c74dcff1c24088d4e5756f764655f8:061c403e-c864-489d-98db-ed33c8fcc815 composerId c99c876b-94eb-4a73-b7a3-d68dd3e86094 (chat “Lab test insights error”, Jul 21–26), composerGenerationID 50eb0f55-a41c-41df-afa7-3e42213cb5a7, toolCallId 70 fc_ot48Arn-3LYxF7-5a0335df-aws_ue1_0
  • inlineDiff:41c74dcff1c24088d4e5756f764655f8:87eefc50-e01d-47ac-9795-d1212a29ee11 composerId e597f193-6cee-4af7-afd3-8580d38ef4c2 (chat “Allergy test marker visibility”, Jul 29–30), composerGenerationID 6a3af5e5-9e77-4911-976b-bde57f9661e2, toolCallId 88 fc_ouD7YXz-4RCkTt-a1ce97a0-aws_ue1_5

Both have hideDecorations: false and an originalTextLines snapshot of 2,165 / 2,163 lines. The file on main is now 2,508 lines. Neither chat is archived.

Why the earlier workarounds didn’t stick

Keep All, deleting Local History, and renaming the file never touch cursorDiskKV. Resetting workspaceStorage/<hash> wouldn’t either: the rows are in globalStorage and keyed by the workspace ID, which is derived from the folder path, so it would come back with the same ID.

What happens on launch

On every relaunch (and every update, since that’s a relaunch) Cursor restores these two overlays. The stored original is ~350 lines out of date, so the reconciliation ends up appending a } to the current file and saving it. Local History logs the write as “Undo Create Diff”. It’s always exactly +1 line, never a wider revert.

What I’m going to try

With Cursor fully quit: back up the two rows into a side table in the same DB, delete them from cursorDiskKV, git restore the file, relaunch. I’ll report back whether the brace stays gone.

Suggestion for the team: inline-diff rows whose originalTextLines no longer match the file on disk (or whose composer hasn’t been touched in N days) probably shouldn’t be re-applied on startup, or at least should be reconciled read-only rather than written back to disk.

Update: cleared it. (at least on app relaunch, haven’t experienced a full app update yet.)

One relaunch after my last post, the two rows had already mutated: the first one’s originalTextLines grew by exactly one line (2,165 → 2,166), and the second was replaced by inlineDiffUndoRedo-87eefc50-…-0a0b7b58-… with the same URI and composer. So the startup restore is reconciling the stale overlays against the current file, writing the +1 } back to disk, and re-persisting the overlay. Explains why Keep All, Local History deletion, and the rename never stuck.

Because the keys move, I matched by content instead. With Cursor fully quit, backed up the DB, then:

create table if not exists inlineDiff_backup_20260916 as
  select key, value from cursorDiskKV
  where key like 'inlineDiff%' and instr(json_extract(value,'$.uri.path'),'LabTestDetailView.swift')>0;
delete from cursorDiskKV
  where key like 'inlineDiff%' and instr(json_extract(value,'$.uri.path'),'LabTestDetailView.swift')>0;

2 rows removed. git restore, relaunch: first launch in two months without the brace. Will confirm after the next update, since that’s been the trigger.

Suggestion: overlays whose originalTextLines no longer match the file on disk shouldn’t be re-applied and written back on startup. Reconcile read-only, or expire them.

Great work digging into this. You basically ended up in the same place as we did, just with DB line level precision. I can confirm your view: the source isn’t in the review UI, Local History, or workspaceStorage. It’s in the inlineDiff:* rows in cursorDiskKV, inside globalStorage/state.vscdb. On startup, restore reconciles a stale originalTextLines against the current file, appends }, and saves. That’s why you see Undo Create Diff in Local History every time. And yep, since the keys mutate between launches, my previous workspaceStorage tip wouldn’t have helped here. You called that out correctly.

A couple notes on your fix:

  • The approach works, and it’s good you backed up the rows before running DELETE. One warning though: cursorDiskKV is internal storage and isn’t meant for manual edits, so keep that backup snapshot handy in case something breaks after an update. If the brace comes back, you can just repeat the same matched-by-content DELETE.
  • Can you confirm here whether the fix survives a full update, not just a relaunch? That was the main trigger, and it’s the last piece we’re missing for the full picture.

The behavior is definitely not intended and it’s not something in your setup. I passed your investigation to the team along with a suggestion like not reapplying an overlay when originalTextLines no longer matches the file on disk, and or expiring those overlays. We’re tracking this issue. I can’t share an ETA yet, but I’ll post here if there’s an update.

Thanks for one of the most detailed investigations I’ve seen. It genuinely helped.

Thanks Dean, and I’m glad it helped!

Confirmed: the fix survives a full update. Cursor updated 3.20.21 → 3.21.13 on relaunch today. LabTestDetailView.swift is clean, no new “Undo Create Diff” entry in Local History (previously one per relaunch), and cursorDiskKV still has zero inlineDiff* rows targeting the file. Two days and one major update since the DELETE with no recurrence.

Great news that the fix survived a full update. That was the last missing piece to complete the picture. Thanks for pushing the debugging all the way down to specific inlineDiff:* rows and confirming that after the DELETE, } doesn’t come back on relaunch or after a major update.

One reminder. cursorDiskKV is internal storage and isn’t meant for manual edits, so keep a backup table handy. If the brace ever comes back after a future update, just repeat the same matched-by-content DELETE.

I shared your finding and suggestion with the team. Don’t reapply the overlay if originalTextLines no longer matches the file on disk, or expire those overlays. This is definitely not intended behavior and not something about your setup. We’re tracking the issue and I can’t share an ETA yet, but I’ll post here if there’s an update.

Thanks again. This is one of the most detailed debug reports I’ve seen.