AIツール深掘り

Vercel本番デプロイ失敗から脆弱性対応まで|個人開発の実録

本番Vercelデプロイ失敗から脆弱性対応まで:個人開発サイトで起きた5つの不具合とその直し方

個人で開発しているオンライン講座サイト(Next.js、Vercelでホスティング)で、2026年10月9日に次々と不具合が発覚しました。本記事は、その日に実際に起きた5つの問題と、どう対処したかをそのまま記録したものです。架空の体験ではなく、実際の開発記録(devlog)に基づく作業ログです。


Vercelのデプロイ履歴が5件連続でError、本番は旧バージョンのまま

Vercelデプロイ失敗のイメージ

Vercelのデプロイ履歴を確認したところ、直近5件が連続でErrorになっており、本番サイトは以前のビルド(Phase15時点)のまま更新されていませんでした。ビルドログには以下のようなエラーが出ていました。

React Hook useMemo is called conditionally(exercise-step.tsx 56行付近)
Failed to build /(learning)/page: / after 3 attempts.(took more than 60 seconds)
Failed to build /(learning)/courses/page: /courses after 3 attempts.(took more than 180 seconds)

まず staticPageGenerationTimeout を180秒に延長して試しましたが、/courses でも同様にタイムアウトしました。最終的には以下の2つの対応で解決しました。

  • useMemo の呼び出し位置を、早期returnより前に移動(optional chainingで空配列を保護)
  • / と /courses を export const dynamic = "force-dynamic" に変更

ローカルで next build が成功することを確認してからpushし、Vercelのビルドが正常終了(Ready)することを確認しました。使用したツールはClaude in Chrome(Vercel管理画面の確認用)、PowerShell、next buildです。


有料講座4〜7が本番に表示されていなかった

本番DBへのseed漏れのイメージ

デプロイ復旧の過程で、本番サイトの /courses に講座が3件しか表示されていないことに気づきました。本番のAPIを直接確認すると、最初はURL誤りで404、次にAPIキー不一致で401が返り、すぐには原因が特定できませんでした。

フロント側のコードにフィルタ処理が入っていないことを確認した上で調査を進めたところ、原因は「講座4〜7のseedが、開発用のNeonブランチにしか実行されていなかった」ことでした。DATABASE_URL を一時的に本番ブランチに差し替え、seed_courses.py を講座1〜7分実行(upsert)して投入し、Vercelの復旧後に /courses で7講座すべての表示を確認しました。使用ツールはPowerShell、uv、seed_courses.py、Claude in Chromeです。


有料講座の最初の1レッスンを無料プレビューにする

無料プレビュー設定のイメージ

有料講座4〜7の最初の1レッスンを、課金なしで閲覧できるようにする対応も同じ日に行いました。実装前にコードを確認したところ、アクセス判定(course_service.get_lesson_detail)が course.is_free のみを参照しており、lesson.is_free というフィールドが用意されているにも関わらず未使用だったことが分かりました。

対応は以下の通りです。

  • 判定条件を not course.is_free and not lesson.is_free に変更
  • 講座4〜7の最初のレッスンを is_free: true にseed更新し、開発・本番の両DBへ投入
  • is_preview の値は変更せず(課金は不要にするが、ログインは必要なまま)

pytestは38件すべてパスし、未ログイン状態で対象レッスンのURLにアクセスすると /login?callbackUrl=... に遷移すること(/upgrade ではないこと)を確認しました。


Docker Desktopが起動不能になり、Dockerを廃止した

Docker廃止後のネイティブ構成のイメージ

開発環境側では、Docker Desktopが以下のエラーで起動しない問題も発生していました。

starting engine: ... vpnkit-bridge handshake failed: unmarshalling handshake: read '<nil>': not a connection to a mulitplexer; received bad magic string
running wslexec: The system cannot find the file specified. Wsl/Service/CreateInstance/CreateVm/HCS/ERROR_FILE_NOT_FOUND

wsl --shutdown、wsl --unregister での各ディストリビューションの削除、Docker Desktopの再インストールを試しましたが解消しませんでした。WSLとVirtualMachinePlatformが有効になっていること、wsl --update が最新であることは確認しましたが、DISM・sfcによるシステムファイルの修復は実施していません。

この時点で復旧を見切り、Dockerの使用自体をやめる判断をしました。backendはuv venv、frontendはpnpmのネイティブ起動に切り替え、DBはNeonに統一し、起動・停止用のstart.bat/stop.batを作成しました。


Next.jsの脆弱性通知(CVE対応)

脆弱性対応のイメージ

同じ日、Vercelのデプロイ失敗の調査中に次の警告が見つかりました。

Vulnerable version of Next.js detected, please update immediately.(Next.js 15.1.3、CVE-2025-66478)

npx fix-react2shell-next を実行するとNext.js 15.1.11への更新案が提示されましたが、同ツールの --fix 実行はタイムアウトし、自動適用はされませんでした。そのため pnpm-workspace.yaml の catalog 内の next のバージョンを手動で15.1.11に書き換え、pnpm installをClaude Codeで実施しました。pytest・Playwrightとも全件パスし、念のため AUTH_SECRET と INTERNAL_API_KEY も予防的に再生成しました。


まとめ:1日で起きた5件の整理

事象 原因 対応 所要時間
Vercelデプロイ5件連続Error useMemoの条件付き呼び出し、SSGタイムアウト useMemo位置修正、force-dynamic化 未計測
有料講座4〜7が非表示 本番DBにseed未実行 seed_courses.pyを本番ブランチに実行 未計測
無料プレビューが機能しない lesson.is_freeが未参照 判定条件を修正しseed更新 未計測
Docker Desktop起動不能 vpnkit-bridge/WSLのハンドシェイク失敗 Docker自体を廃止、ネイティブ構成に移行 未計測
Next.js脆弱性通知 CVE-2025-66478 バージョン手動更新、鍵の再生成 未計測

この日はVercelのデプロイ復旧作業の途中で、DBのseed漏れ、機能不足、環境構築の問題、脆弱性対応が次々と発覚し、1件ずつ原因を確認しながら対応する形になりました。使用した主なツールはPowerShell、next build、pytest、uv、pnpm、Claude in Chrome、Claude Codeです。

この記事は運営者の実際の開発記録をもとに、AIの支援を受けて作成しています。