Tutorial: How to Fix "Loading Chat" and Recover History (Cursor v2.3.x)

The Problem: After an update or Windows restart, Cursor gets stuck in an infinite “Loading Chat” loop and fails to load history. This happens because the main database file (state.vscdb) became corrupted, but Cursor created an emergency backup file that it cannot restore automatically.

Diagnosis: Checking the folder structure in %APPDATA%\Cursor\User\globalStorage revealed the presence of files named state.vscdb.corrupted.... This confirmed that my data wasn’t deleted, but moved to a file Cursor stopped reading.

:hammer_and_wrench: The Solution

Step 1: Close Cursor Ensure Cursor is completely closed (check Task Manager if necessary) to unlock the database files.

Step 2: Access the Global Data Folder

  1. Press Win + R on your keyboard.

  2. Type the command below and hit Enter: %APPDATA%\Cursor\User\globalStorage

Step 3: Identify and Swap the Files You will see three types of important files:

  • state.vscdb (The current file that is stuck/broken).

  • state.vscdb.backup (A standard automatic backup).

  • state.vscdb.corrupted.1767... (:police_car_light: THE FILE WITH YOUR DATA! The number will be different on your PC).

Do the following:

  1. Create a new folder named OLD and move the state.vscdb and state.vscdb.backup files into it (this clears the area without permanently deleting anything).

  2. Locate the long file containing .corrupted. in its name.

  3. Rename this file to simply: state.vscdb.

Step 4: Open Cursor Upon launching, Cursor will read the file you renamed. Since it contains the healthy data from before the crash, your chats and settings should reappear immediately.


:envelope_with_arrow: Contact & Partnerships: If this guide saved your day and you’d like to reach out for partnerships, contact me at: [email protected] (I’m a dev from Brazil, and keeping up with the Cursor Pro subscription is a real struggle! :sweat_smile:)

Here’s a PowerShell script, run this, and it should work :slight_smile:

PowerShell Script
# Cursor Chat Recovery Script
# Automatically fixes "Loading Chat" issue by restoring corrupted database files
# Based on tutorial: https://community.cursor.com/t/tutorial-how-to-fix-loading-chat-and-recover-history-cursor-v2-3-x/12345

$ErrorActionPreference = "Stop"

$globalStoragePath = "$env:APPDATA\Cursor\User\globalStorage"
$oldFolderPath = Join-Path $globalStoragePath "OLD"

Write-Host "Cursor Chat Recovery Script" -ForegroundColor Cyan
Write-Host "============================" -ForegroundColor Cyan
Write-Host ""

# Step 1: Check if Cursor is running
Write-Host "Step 1: Checking if Cursor is running..." -ForegroundColor Yellow
$cursorProcesses = Get-Process -Name "Cursor" -ErrorAction SilentlyContinue

if ($cursorProcesses) {
    Write-Host "WARNING: Cursor is currently running!" -ForegroundColor Red
    Write-Host "Found $($cursorProcesses.Count) Cursor process(es)." -ForegroundColor Red
    Write-Host ""
    Write-Host "Please close Cursor completely before running this script." -ForegroundColor Yellow
    Write-Host "You can close it manually or press Ctrl+C to exit this script." -ForegroundColor Yellow
    Write-Host ""
    $response = Read-Host "Do you want to close Cursor now? (Y/N)"
    
    if ($response -eq "Y" -or $response -eq "y") {
        Write-Host "Closing Cursor processes..." -ForegroundColor Yellow
        $cursorProcesses | Stop-Process -Force
        Start-Sleep -Seconds 2
        Write-Host "Cursor closed." -ForegroundColor Green
    } else {
        Write-Host "Exiting. Please close Cursor manually and run this script again." -ForegroundColor Yellow
        exit 1
    }
} else {
    Write-Host "Cursor is not running. Proceeding..." -ForegroundColor Green
}

Write-Host ""

# Step 2: Check if globalStorage folder exists
Write-Host "Step 2: Checking globalStorage folder..." -ForegroundColor Yellow
if (-not (Test-Path $globalStoragePath)) {
    Write-Host "ERROR: globalStorage folder not found at: $globalStoragePath" -ForegroundColor Red
    exit 1
}
Write-Host "globalStorage folder found." -ForegroundColor Green
Write-Host ""

# Step 3: Look for corrupted files
Write-Host "Step 3: Searching for corrupted database files..." -ForegroundColor Yellow
$corruptedFiles = Get-ChildItem -Path $globalStoragePath -Filter "*corrupted*" -ErrorAction SilentlyContinue

if (-not $corruptedFiles) {
    Write-Host "No corrupted files found in globalStorage." -ForegroundColor Yellow
    Write-Host ""
    Write-Host "This could mean:" -ForegroundColor Cyan
    Write-Host "  - The issue hasn't occurred yet" -ForegroundColor Cyan
    Write-Host "  - The corrupted files were already cleaned up" -ForegroundColor Cyan
    Write-Host "  - The issue is elsewhere" -ForegroundColor Cyan
    Write-Host ""
    Write-Host "Current database files:" -ForegroundColor Cyan
    Get-ChildItem -Path $globalStoragePath -Filter "state.vscdb*" | ForEach-Object {
        Write-Host "  - $($_.Name) ($([math]::Round($_.Length / 1MB, 2)) MB)" -ForegroundColor Gray
    }
    Write-Host ""
    Write-Host "If you're experiencing the 'Loading Chat' issue, try:" -ForegroundColor Yellow
    Write-Host "  1. Close Cursor completely" -ForegroundColor Yellow
    Write-Host "  2. Wait a few seconds" -ForegroundColor Yellow
    Write-Host "  3. Run this script again" -ForegroundColor Yellow
    Write-Host ""
    exit 0
}

Write-Host "Found $($corruptedFiles.Count) corrupted file(s):" -ForegroundColor Green
$corruptedFiles | ForEach-Object {
    Write-Host "  - $($_.Name) ($([math]::Round($_.Length / 1MB, 2)) MB)" -ForegroundColor Gray
}
Write-Host ""

# Step 4: Create OLD folder and move current files
Write-Host "Step 4: Creating backup folder and moving current files..." -ForegroundColor Yellow

if (-not (Test-Path $oldFolderPath)) {
    New-Item -ItemType Directory -Path $oldFolderPath -Force | Out-Null
    Write-Host "Created OLD folder." -ForegroundColor Green
} else {
    Write-Host "OLD folder already exists." -ForegroundColor Yellow
}

# Move current state.vscdb and backup files
$filesToMove = @("state.vscdb", "state.vscdb.backup", "state.vscdb-shm", "state.vscdb-wal")
$movedCount = 0

foreach ($fileName in $filesToMove) {
    $filePath = Join-Path $globalStoragePath $fileName
    if (Test-Path $filePath) {
        $destPath = Join-Path $oldFolderPath $fileName
        Move-Item -Path $filePath -Destination $destPath -Force -ErrorAction SilentlyContinue
        if (Test-Path $destPath) {
            Write-Host "  Moved: $fileName" -ForegroundColor Gray
            $movedCount++
        }
    }
}

if ($movedCount -gt 0) {
    Write-Host "Moved $movedCount file(s) to OLD folder." -ForegroundColor Green
} else {
    Write-Host "No files to move (they may have been moved already)." -ForegroundColor Yellow
}
Write-Host ""

# Step 5: Restore the most recent corrupted file
Write-Host "Step 5: Restoring corrupted database file..." -ForegroundColor Yellow

# Get the most recent corrupted file (by LastWriteTime)
$latestCorrupted = $corruptedFiles | Sort-Object LastWriteTime -Descending | Select-Object -First 1

if ($latestCorrupted) {
    $newStatePath = Join-Path $globalStoragePath "state.vscdb"
    
    Write-Host "Restoring: $($latestCorrupted.Name)" -ForegroundColor Cyan
    Write-Host "  Size: $([math]::Round($latestCorrupted.Length / 1MB, 2)) MB" -ForegroundColor Gray
    Write-Host "  Date: $($latestCorrupted.LastWriteTime)" -ForegroundColor Gray
    
    Copy-Item -Path $latestCorrupted.FullName -Destination $newStatePath -Force
    
    if (Test-Path $newStatePath) {
        Write-Host ""
        Write-Host "SUCCESS! Database file restored." -ForegroundColor Green
        Write-Host ""
        Write-Host "Next steps:" -ForegroundColor Cyan
        Write-Host "  1. Open Cursor" -ForegroundColor Yellow
        Write-Host "  2. Your chat history should be restored" -ForegroundColor Yellow
        Write-Host ""
        Write-Host "Note: Your old files are safely stored in:" -ForegroundColor Gray
        Write-Host "  $oldFolderPath" -ForegroundColor Gray
    } else {
        Write-Host "ERROR: Failed to restore database file." -ForegroundColor Red
        exit 1
    }
} else {
    Write-Host "ERROR: Could not find corrupted file to restore." -ForegroundColor Red
    exit 1
}

Write-Host ""
Write-Host "Script completed successfully!" -ForegroundColor Green

I cant open history chat 20d ago, it stuck on ‘loading chat’. No corrupted file found in that location. I only get state.vscdb, state.vscdb.backup, state.vscdb.options.json, state.vscdb-shm state.vscdb-wal and storage.json.

Really need that history chat…

Toggle Developers Tools console output:

ERR An unknown error occurred. Please consult the log for more details. Object[[Prototype]]: Objectconstructor: ƒ Object()hasOwnProperty: ƒ hasOwnProperty()isPrototypeOf: ƒ isPrototypeOf()propertyIsEnumerable: ƒ propertyIsEnumerable()toLocaleString: ƒ toLocaleString()toString: ƒ toString()valueOf: ƒ valueOf()defineGetter: ƒ defineGetter()defineSetter: ƒ defineSetter()lookupGetter: ƒ lookupGetter()lookupSetter: ƒ lookupSetter()proto: (…)get proto: ƒ proto()set proto: ƒ proto()
error @ workbench.desktop.main.js:55
workbench.desktop.main.js:15616 Error: [composer] No composer data handle found
at uv.updateComposerData (workbench.desktop.main.js:646:15661)
at workbench.desktop.main.js:52:45021
at VSr (workbench.desktop.main.js:52:44707)
at Y9 (workbench.desktop.main.js:52:44668)
at n.value (workbench.desktop.main.js:52:45010)
at W0.updateComposer (workbench.desktop.main.js:13849:19053)
at workbench.desktop.main.js:52:45021
at VSr (workbench.desktop.main.js:52:44707)
at Y9 (workbench.desktop.main.js:52:44668)
at n.value (workbench.desktop.main.js:52:45010)
at W0.showComposerHistory (workbench.desktop.main.js:13857:2868)
at workbench.desktop.main.js:52:45021
at VSr (workbench.desktop.main.js:52:44707)
at Y9 (workbench.desktop.main.js:52:44668)
at n.value (workbench.desktop.main.js:52:45010)
at Nau.run (workbench.desktop.main.js:13059:7941)
at workbench.desktop.main.js:52:45021
at VSr (workbench.desktop.main.js:52:44707)
at Y9 (workbench.desktop.main.js:52:44668)
at n.value (workbench.desktop.main.js:52:45010)
at handler (workbench.desktop.main.js:54:18354)
at KHo.invokeFunction (workbench.desktop.main.js:14076:960)
at workbench.desktop.main.js:13614:3145
at VSr (workbench.desktop.main.js:52:44707)
at Y9 (workbench.desktop.main.js:52:44668)
at NSo._tryExecuteCommand (workbench.desktop.main.js:13614:2998)
at NSo.executeCommandImpl (workbench.desktop.main.js:13614:2243)
at NSo.executeCommand (workbench.desktop.main.js:13614:1896)
at Kes.run (workbench.desktop.main.js:54:35025)
at Cx.runAction (workbench.desktop.main.js:52:53162)
at Cx.run (workbench.desktop.main.js:52:53065)
at RP.onClick (workbench.desktop.main.js:437:93499)
at HTMLLIElement. (workbench.desktop.main.js:421:17700)
onDidChangeNotification @ workbench.desktop.main.js:15616
2workbench.desktop.main.js:15616 Error: [composer] No composer data handle found
at uv.updateComposerData (workbench.desktop.main.js:646:15661)
at workbench.desktop.main.js:52:45021
at VSr (workbench.desktop.main.js:52:44707)
at Y9 (workbench.desktop.main.js:52:44668)
at n.value (workbench.desktop.main.js:52:45010)
at W0.updateComposer (workbench.desktop.main.js:13849:19053)
at workbench.desktop.main.js:52:45021
at VSr (workbench.desktop.main.js:52:44707)
at Y9 (workbench.desktop.main.js:52:44668)
at n.value (workbench.desktop.main.js:52:45010)
at W0.showComposerHistory (workbench.desktop.main.js:13857:2868)
at workbench.desktop.main.js:52:45021
at VSr (workbench.desktop.main.js:52:44707)
at Y9 (workbench.desktop.main.js:52:44668)
at n.value (workbench.desktop.main.js:52:45010)
at Nau.run (workbench.desktop.main.js:13059:7941)
at workbench.desktop.main.js:52:45021
at VSr (workbench.desktop.main.js:52:44707)
at Y9 (workbench.desktop.main.js:52:44668)
at n.value (workbench.desktop.main.js:52:45010)
at handler (workbench.desktop.main.js:54:18354)
at KHo.invokeFunction (workbench.desktop.main.js:14076:960)
at workbench.desktop.main.js:13614:3145
at VSr (workbench.desktop.main.js:52:44707)
at Y9 (workbench.desktop.main.js:52:44668)
at NSo._tryExecuteCommand (workbench.desktop.main.js:13614:2998)
at NSo.executeCommandImpl (workbench.desktop.main.js:13614:2243)
at NSo.executeCommand (workbench.desktop.main.js:13614:1896)
at Kes.run (workbench.desktop.main.js:54:35025)
at Cx.runAction (workbench.desktop.main.js:52:53162)
at Cx.run (workbench.desktop.main.js:52:53065)
at RP.onClick (workbench.desktop.main.js:437:93499)
at HTMLLIElement. (workbench.desktop.main.js:421:17700)
onDidChangeNotification @ workbench.desktop.main.js:15616
(anonymous) @ workbench.desktop.main.js:15616
_deliver @ workbench.desktop.main.js:49
_deliverQueue @ workbench.desktop.main.js:49
fire @ workbench.desktop.main.js:49
addNotification @ workbench.desktop.main.js:10416
error @ workbench.desktop.main.js:13630
(anonymous) @ workbench.desktop.main.js:13084
_deliver @ workbench.desktop.main.js:49
_deliverQueue @ workbench.desktop.main.js:49
fire @ workbench.desktop.main.js:49
run @ workbench.desktop.main.js:52
await in run
onClick @ workbench.desktop.main.js:437
(anonymous) @ workbench.desktop.main.js:421

version

Version: 2.3.35 (user setup)
VSCode Version: 1.105.1
Commit: cf8353edc265f5e46b798bfb276861d0bf3bf120
Date: 2026-01-13T07:39:18.564Z
Electron: 37.7.0
Chromium: 138.0.7204.251
Node.js: 22.20.0
V8: 13.8.258.32-electron.0
OS: Windows_NT x64 10.0.19045