開発メモ
@nuxt/content「UNIQUE constraint failed: _content_pages.hash」エラーの原因と解決策
結論
SQLiteキャッシュファイルを削除すれば解決する。
# devサーバーを停止してから実行
rm -rf apps/web/.data/content/
PowerShellの場合:
Remove-Item -Recurse -Force apps/web/.data/content/
エラーの症状
pnpm devでNuxt開発サーバーを起動すると、以下のエラーが大量に出力される:
ERROR [unhandledRejection] UNIQUE constraint failed: _content_pages.__hash__
ERROR [unhandledRejection] UNIQUE constraint failed: _content_pages.id
エラーは数十回繰り返し出力され、開発サーバーが正常に動作しない。
原因
@nuxt/contentはコンテンツをSQLiteデータベースにインデックスして管理している。
| ファイル | 役割 |
|---|---|
.data/content/contents.sqlite | コンテンツのキャッシュDB |
コンテンツファイルを削除しても、SQLiteキャッシュには古いエントリが残る。
新しいコンテンツを追加したとき、古いエントリとハッシュ値やIDが衝突し、UNIQUE制約違反が発生する。
今回のケース
git statusを確認すると、以下のファイルが削除されていた:
gsc-redirect-trailing-slash.md(削除済み)sitemap-canonical-mismatch-fix.md(削除済み)
新しいファイル gsc-trailing-slash-mismatch.md を追加した際に、SQLiteキャッシュ内の古いエントリと衝突した。
解決手順
1. devサーバーを停止
SQLiteファイルがロックされるため、まずdevサーバーを停止する。
- ターミナルで Ctrl+C を押す
- または、使用しているポートのプロセスを終了:
# ポート3000の場合
Get-NetTCPConnection -LocalPort 3000 -State Listen | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force }
# ポート3001の場合
Get-NetTCPConnection -LocalPort 3001 -State Listen | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force }
2. キャッシュディレクトリを削除
Remove-Item -Recurse -Force apps/web/.data/content/
Git Bashの場合:
rm -rf apps/web/.data/content/
3. devサーバーを再起動
pnpm dev
SQLiteデータベースが自動的に再生成され、エラーが解消される。
ファイルがロックされている場合
「The process cannot access the file」エラーが出る場合、別のプロセスがファイルを使用している。
確認方法
- リソースモニターを起動:
resmon
- CPU タブ → 関連するハンドル で
contents.sqliteを検索 - ロックしているプロセスを特定して終了
よくある原因
- VSCode/Cursorなどのエディタがファイルをウォッチしている
- 別のターミナルでdevサーバーが動いている
- IDEのTypeScript Language Serverがファイルを参照している
まとめ
| 項目 | 内容 |
|---|---|
| エラー | UNIQUE constraint failed: _content_pages.__hash__ |
| 原因 | 削除したMDファイルのエントリがSQLiteキャッシュに残っている |
| 解決策 | .data/content/ ディレクトリを削除して再生成 |
| 予防 | コンテンツファイルを大量削除した後は、キャッシュクリアを習慣化する |