
先日、Cursorのアップデートに失敗して起動しなくなってしまいました。
手を尽くしたのですが再インストールせざるを得ない状況。
そこで休日返上で履歴の復元にチャレンジしたので、Cursorの履歴保存のしくみと復元方法とスクリプトを共有します。
こんな人向けの記事です
- PCを買い替えた人・初期化した人
- Cursorを再インストールしたい人
- WSL環境の作り直し等で、Cursorのチャット履歴も復元したい人
動作確認環境
- OS:Windows 11
- PowerShell:5.1
- Cursor:2.4(2026年2月時点)
Cursorは頻繁にバージョンアップが繰り返されていますので、掲載したスニペットは正常に動作しない可能性があります。
本記事のスニペットをコピペで使用する際は、自己責任ということでご理解ください。
なぜ履歴が消えるのか?
Cursorの会話履歴のフォルダ管理のしくみ
Cursorはチャット履歴を、プロジェクトフォルダごとに分けて管理しています。その保存先は、Windowsであれば以下のパスです。
C:\Users\<ユーザー名>\AppData\Roaming\Cursor\User\workspaceStorage\

このフォルダの中には、44e5471f3443e2b32bd8a8166070f6a5 のような 32桁の英数字(ハッシュ値) を名前に持つフォルダが大量に並んでいます。

このハッシュ値は、プロジェクトフォルダのパス(URI)から自動生成されます。
問題は環境が変わると「ハッシュ値(フォルダ名)」も変わるということ
たとえば、WSLをUbuntu22.04からUbuntu24.04にバージョンアップするケースではURLが変わるため、結果としてハッシュ値(フォルダ名)が変わってしまいます。
| 環境 | プロジェクトのURI(例) |
|---|---|
| 旧WSL環境 | vscode-remote://wsl+Ubuntu-22.04/home/user/myproject |
| 新WSL環境 | vscode-remote://wsl+Ubuntu-24.04/home/user/myproject |
この場合、Cursorは新しい(空っぽの)新ハッシュフォルダを見に行ってしまいます。結果的にCursorは古いハッシュ値(フォルダ名)の会話履歴を読み込むことができなくなってしまいます。
しかし逆に、ハッシュ値(フォルダ名)を入れ替えることで履歴を復元できるはずです。
履歴復元のアプローチ
流れはシンプルです。「新旧のハッシュフォルダを突き合わせて、中身だけ移植する」だけです。
- : 新しい環境でプロジェクトを一度開き、新ハッシュフォルダを作らせる
- : バックアップ(旧ハッシュ)の中身(
state.vscdb)を、新ハッシュのフォルダに上書きコピーする - :
globalStorageのDBも合わせて戻すことで、インデックス不整合による「Loading…」フリーズを防ぐ(WSL環境の場合に特に有効)
復元前の準備
以下の例は念の為、会話履歴以外(globalStrage等)もバックアップしていますが、最も重要なのはworkspaceStorageで、これが会話履歴本体です。
$BK = "G:\260213CursorBK" #バックアップ先を指定する
New-Item -ItemType Directory -Force -Path $BK | Out-Null
# 1) チャット履歴(最重要)
$src1 = Join-Path $env:APPDATA "Cursor\User\workspaceStorage"
if (Test-Path $src1) {
robocopy $src1 (Join-Path $BK "Roaming_Cursor_User_workspaceStorage") /E /COPY:DAT /DCOPY:T /R:1 /W:1 /XJ
}
# 2) Cursor の Roaming 全体(設定など。容量が大きければ後で絞ってOK)
$src2 = Join-Path $env:APPDATA "Cursor"
if (Test-Path $src2) {
robocopy $src2 (Join-Path $BK "Roaming_Cursor") /E /COPY:DAT /DCOPY:T /R:1 /W:1 /XJ
}
# 3) .cursor(存在する場合。拡張/データが入っていることがある)
$src3 = Join-Path $env:USERPROFILE ".cursor"
if (Test-Path $src3) {
robocopy $src3 (Join-Path $BK "UserProfile_.cursor") /E /COPY:DAT /DCOPY:T /R:1 /W:1 /XJ
}
# 4) Local 側の Cursor データ(存在する場合)
$src4 = Join-Path $env:LOCALAPPDATA "Cursor"
if (Test-Path $src4) {
robocopy $src4 (Join-Path $BK "Local_Cursor") /E /COPY:DAT /DCOPY:T /R:1 /W:1 /XJ
}
続いてバックアップした古い会話履歴フォルダのハッシュ値(会話履歴のフォルダ名)との対応表を作ります。
これは必ずしも必要ありませんが、特にプロジェクトがたくさんある場合は、Cursorを再インストールした後で生成される新しい会話履歴フォルダのハッシュを古いフォルダのハッシュと入れ替える際に役に立ちます。
$ws = "G:\260213CursorBK\Roaming_Cursor_User_workspaceStorage"
$rows = foreach ($dir in Get-ChildItem $ws -Directory) {
$wj = Join-Path $dir.FullName "workspace.json"
if (-not (Test-Path $wj)) { continue }
try {
$j = Get-Content $wj -Raw | ConvertFrom-Json
} catch {
continue
}
$folder = $null
if ($j.PSObject.Properties.Name -contains "folder") { $folder = $j.folder }
if (-not $folder -and ($j.PSObject.Properties.Name -contains "workspace")) { $folder = $j.workspace }
[pscustomobject]@{
HashFolder = $dir.Name
WorkspaceUri = $folder
WorkspaceJson= $wj
}
}
$rows |
Sort-Object WorkspaceUri |
Export-Csv -NoTypeInformation -Encoding UTF8 "$ws\_workspace_map.csv"
$rows | Select-Object -First 20 HashFolder, WorkspaceUri
このスクリプトを実行すると、”G:\260213CursorBK\Roaming_Cursor_User_workspaceStorage”内に、「_workspace_map.csv」という名前で、以下のようなCSVデータが生成されるはずです。

CSVの各列の意味
| 列名 | 何を表しているか | ユーザーにとっての意味 |
|---|---|---|
| HashFolder | バックアップフォルダ内に作られている「32桁のランダムな文字列(ハッシュ)」のフォルダ名です。 | Cursorが履歴を管理するための「ハッシュ値」であり、フォルダ名をハッシュ関数でハッシュ化した値です。人間には解読できません。 |
| WorkspaceUri | そのハッシュフォルダと紐づいている「プロジェクトの実際の場所(パス)」です | 「どのプロジェクトの履歴か」を示す最も重要な部分です。ここを見て、自分が復元したいプロジェクトを探します。(→「旧ハッシュ($oldHash)の見つけ方」参照) |
| WorkspaceJson | パス情報が記録されていた workspace.json というファイルの保存場所です。 | (ここは基本的に見なくてOKです。スクリプトが読み込んだファイルの場所を示しているだけです) |
スクリプト実行前に必ずCursorを完全終了させてください。 DBファイルがロックされたままだとコピーに失敗します。
通常の × ボタンではバックグラウンドで動き続けることがあります。以下の手順で完全終了させてください。
- タスクバー右下の通知領域(システムトレイ)を開く
- Cursorのアイコンを右クリック
- 「終了」または「Quit」 をクリック

既存データが上書きされます。 不安な場合は、実行前に新環境側の workspaceStorage フォルダもバックアップしておくと安心です。
旧ハッシュ($oldHash)の見つけ方(WorkspaceUriの探し方)
バックアップフォルダの中にある各ハッシュフォルダには、workspace.json というファイルが1つあります。これをテキストエディタで開くと、そのプロジェクトのパスが記録されています。
{
"folder": "file:///C%3A/Users/user/myproject"
}または WSL の場合:
{
"folder": "vscode-remote://wsl%2BUbuntu-22.04/home/user/myproject"
}folder の値を見て、復元したいプロジェクトと一致するフォルダを特定します。そのフォルダ名(32桁のハッシュ値)が、後述のスクリプトで $oldHash に設定する値です。
パターン1:Windowsのローカルフォルダ
file:///e%3A/win_n8n や file:///g%3A/basketball_sentinel
- 解説:
file:///から始まっているのは、自分のPCのローカルドライブにあるフォルダです。%3Aは「:(コロン)」のことです。
つまり、これはE:\win_n8nやG:\basketball_sentinelというフォルダを開いたときの履歴であることを意味しています。
パターン2:WSL(Windows Subsystem for Linux)のフォルダ
vscode-remote://wsl%2Bubuntu/home/ofbita/basketball_sentinel
- 解説:
vscode-remote://wslから始まっているのは、WSL環境(Linux)の中にあるフォルダです。%2Bは「+(プラス)」のことです。
つまり、これは WSLのUbuntuの中にある/home/ofbita/basketball_sentinelというフォルダを開いたときの履歴です。
パターン3:エクスプローラーからネットワーク経由で開いたWSL
file://wsl.localhost/Ubuntu/home/ofbita/llm_worker
- 解説: これもWSL内のフォルダですが、Cursorの「WSLに接続」機能を使わず、Windowsのエクスプローラーから
\\wsl.localhost\...のように無理やり開いたときのパスです。
パターン4:SSH(遠隔サーバー)のフォルダ
vscode-remote://ssh-remote%2B7b22686f.../etc
- 解説:
ssh-remoteから始まっているのは、VPSやクラウドサーバーなどにSSHでリモート接続したときのフォルダです。
途中の長い文字列は、接続先のサーバー情報が暗号化されたものです。
大量にある場合の一括確認コマンド
# ↓ 自分のバックアップフォルダのパスに書き換えてください
$backupWs = "G:\260213CursorBK\Roaming_Cursor_User_workspaceStorage"
Get-ChildItem $backupWs -Directory | ForEach-Object {
$jsonPath = Join-Path $_.FullName "workspace.json"
if (Test-Path $jsonPath) {
$content = Get-Content $jsonPath -Raw | ConvertFrom-Json
[PSCustomObject]@{
Hash = $_.Name
Folder = $content.folder
}
}
} | Format-Table -AutoSize実行すると以下のように一覧が出るので、目的のプロジェクトのハッシュをすぐに特定できます。
PowerShellでの実行イメージ

復元スクリプト
さて、ここまでの作業で以下の必要な変数を埋めることができると思います。
これを使ってGeminiさんに作成してもらったスクリプトに当てはめれば復元できるはずです。
Windowsローカル版・日本語パス完全対応バージョン
書き換えが必要な3箇所
| 変数 | 説明 | 例 |
|---|---|---|
$backupWs | バックアップ先のフォルダパス | G:\260213CursorBK\Roaming_Cursor_User_workspaceStorage |
$oldHash | 旧環境のハッシュ(32桁の英数字) | 44e5471f3443e2b32bd8a8166070f6a5 |
$folderPart | プロジェクトフォルダ名の一部(検索用) | CSV整形(日本語・スペースOK) |
# ==========================================
# Cursor チャット履歴復元
# Windowsローカル・日本語パス完全対応版
# ==========================================
# ===== ここを書き換えてください(3箇所) =====
$backupWs = "G:\260213CursorBK\Roaming_Cursor_User_workspaceStorage"
$oldHash = "44e5471f3443e2b32bd8a8166070f6a5" # 旧ハッシュ
$folderPart = "CSV整形" # プロジェクト名の一部(日本語・スペースOK)
# =============================================
# --- 処理開始 ---
$newWsRoot = Join-Path $env:APPDATA "Cursor\User\workspaceStorage"
# URLエンコード処理(日本語・スペースを %XX 形式に変換する安全な方式)
$encodedPart = [Uri]::EscapeDataString($folderPart).ToUpper()
Write-Host "検索中... キーワード: '$folderPart' (または '$encodedPart')" -ForegroundColor Gray
# 新ハッシュを探す
$newHash = Get-ChildItem $newWsRoot -Directory | Where-Object {
$jsonPath = Join-Path $_.FullName "workspace.json"
if (Test-Path $jsonPath) {
$content = Get-Content $jsonPath -Raw
if ($content -match "file:///") {
return ($content -match [Regex]::Escape($folderPart) -or $content -match $encodedPart)
}
}
return $false
} | Select-Object -First 1 -ExpandProperty Name
if (-not $newHash) {
Write-Error "新環境でプロジェクトが見つかりません。Cursorで一度フォルダを開きましたか?`n(検索キー: $folderPart / $encodedPart)"
exit
}
Write-Host "新ハッシュを発見: $newHash" -ForegroundColor Green
$srcDir = Join-Path $backupWs $oldHash
$dstDir = Join-Path $newWsRoot $newHash
if (-not (Test-Path $srcDir)) {
Write-Error "バックアップ元が見つかりません: $srcDir"
exit
}
# 退避(既存データを _OLD フォルダへ)
New-Item -ItemType Directory -Force -Path (Join-Path $dstDir "_OLD") | Out-Null
Get-ChildItem -Path $dstDir -Filter "state.vscdb*" | Move-Item -Force -Destination (Join-Path $dstDir "_OLD")
# コピー(旧DBを新フォルダへ上書き)
Get-ChildItem -Path $srcDir -Filter "state.vscdb*" | Copy-Item -Destination $dstDir -Force
Write-Host "復元完了!Cursorを起動してください。" -ForegroundColor CyanWSL環境バージョン
WSLの場合は、globalStorage のDBも合わせて戻さないと 「Loading…」フリーズ が発生することがあります。
書き換えが必要な4箇所
| 変数 | 説明 | 例 |
|---|---|---|
$backupWs | workspaceStorage のバックアップパス | G:\260213CursorBK\Roaming_Cursor_User_workspaceStorage |
$backupGs | globalStorage のバックアップパス | G:\260213CursorBK\Roaming_Cursor_User_globalStorage |
$oldHash | 旧環境のハッシュ(32桁の英数字) | b5ed5e9f85b2d7c3a1234567890abcde |
$folderPart | プロジェクト名の一部(検索用) | myproject |
# ==========================================
# Cursor チャット履歴復元
# WSL環境対応版(globalStorage含む)
# ==========================================
# ===== ここを書き換えてください(4箇所) =====
$backupWs = "G:\260213CursorBK\Roaming_Cursor_User_workspaceStorage"
$backupGs = "G:\260213CursorBK\Roaming_Cursor_User_globalStorage"
$oldHash = "b5ed5e9f85b2d7c3a1234567890abcde" # 旧ハッシュ
$folderPart = "myproject" # プロジェクト名の一部(英語推奨・日本語も可)
# =============================================
$newWsRoot = Join-Path $env:APPDATA "Cursor\User\workspaceStorage"
# URLエンコード処理(日本語・スペースを %XX 形式に変換する安全な方式)
$encodedPart = [Uri]::EscapeDataString($folderPart).ToUpper()
Write-Host "検索中... キーワード: '$folderPart' (または '$encodedPart')" -ForegroundColor Gray
# 新ハッシュを探す(WSLパスを対象)
$newHash = Get-ChildItem $newWsRoot -Directory | Where-Object {
$jsonPath = Join-Path $_.FullName "workspace.json"
if (Test-Path $jsonPath) {
$content = Get-Content $jsonPath -Raw
if ($content -match "vscode-remote://") {
return ($content -match [Regex]::Escape($folderPart) -or $content -match $encodedPart)
}
}
return $false
} | Select-Object -First 1 -ExpandProperty Name
if (-not $newHash) {
Write-Error "新環境でプロジェクトが見つかりません。Cursorで一度WSLフォルダを開きましたか?"
exit
}
Write-Host "新ハッシュを発見: $newHash" -ForegroundColor Green
# --- workspaceStorage の復元 ---
$srcDir = Join-Path $backupWs $oldHash
$dstDir = Join-Path $newWsRoot $newHash
if (-not (Test-Path $srcDir)) {
Write-Error "バックアップ元が見つかりません: $srcDir"
exit
}
New-Item -ItemType Directory -Force -Path (Join-Path $dstDir "_OLD") | Out-Null
Get-ChildItem -Path $dstDir -Filter "state.vscdb*" | Move-Item -Force -Destination (Join-Path $dstDir "_OLD")
Get-ChildItem -Path $srcDir -Filter "state.vscdb*" | Copy-Item -Destination $dstDir -Force
Write-Host "[1/2] workspaceStorage の復元完了" -ForegroundColor Green
# --- globalStorage の復元(Loading...フリーズ防止) ---
$newGsRoot = Join-Path $env:APPDATA "Cursor\User\globalStorage"
$targetVsdb = "state.vscdb"
if (Test-Path $backupGs) {
$srcGs = Join-Path $backupGs $targetVsdb
$dstGs = Join-Path $newGsRoot $targetVsdb
if (Test-Path $srcGs) {
Copy-Item $srcGs -Destination $dstGs -Force
Write-Host "[2/2] globalStorage の復元完了" -ForegroundColor Green
} else {
Write-Warning "globalStorage のバックアップが見つかりませんでした(スキップ)"
}
} else {
Write-Warning "globalStorage バックアップフォルダが存在しません(スキップ)"
}
Write-Host "復元完了!Cursorを起動してください。" -ForegroundColor Cyan実際にやってみます
「復元前の準備」が終わっていることを必ず確認してくださいね。
今回はWSL環境対応版です。実質調べるのは「バックアップ場所」($backupWsと$backupGs)と「旧ハッシュ値」($oldHash)のみです。($folderPartは正直不要な気もしますが、余計なトークン使うのでそこはGeminiさんと議論はしていません。)


以上です。
Cursorを起動し、対象のプロジェクトを開いたとき、チャット履歴パネルに過去の会話が表示されていれば成功です。
Before

After

- Cursorを完全に終了させること。 手順は「復元前の準備」を参照してください。
- WSL版でのディストリビューション名 は
wsl -l -vコマンドで確認できます。$folderPartの検索キーワードにディストリビューション名の一部(例:Ubuntu-24)を含めることで、さらに絞り込みが可能です。
