Next.js 16.2 Server Functionログでエラー10分特定

Next.jsのServer Actionsを触っていて、「ローカルでは再現しないのに本番だけ500になる」を何度も経験していませんか。この記事は、Next.js 16.2以降で障害調査の速度を上げたい人に向けて書いています。読むと、開発時ログの取り方から本番での原因特定まで、10分で初動できる型が手に入ります。僕は福祉事業のIT全般を担当しながら、AI×SaaS開発を複業で回しているので、非エンジニア部門とも共有しやすい運用テンプレとしてまとめます。

こんな方におすすめ

  • Next.js Server Actions デバッグで、開発と本番の差分に悩んでいる方
  • Vercel 本番エラー 調査を担当しているけど、毎回手順がブレる方
  • チームで障害対応を標準化したいけど、ドキュメント化が進んでいない方
  • 非エンジニアにも説明できる運用フローを作りたい方

この記事でわかること

  • Next.js 16.2 Server Function ログの正しい見方
  • next.configで観測性を上げる具体的な設定
  • VercelのCLIで500を10分以内に切り分ける順番
  • digestを軸にした再発防止までの運用テンプレ

公開前確認(2026年5月時点):Next.js 16.2の logging.serverFunctions は開発時に既定ON、logging.browserToTerminalerror / warn / true / false を選べます。本番調査ではVercel Logs、request-id、deployment URL、Next.jsの digest を突き合わせる前提で運用してください。

僕は福祉事業のIT全般を担当しつつ、準委任でAI×SaaS開発、個人では受託開発とAI活用支援を行っています。ITの言葉を非ITの現場へ翻訳する「異世界転生」視点で、今日から使える形に落として解説します。

Next.js 16.2で変わった観測ポイントを先に押さえる

まず前提です。Next.js 16.2は2026年3月18日に公開され、公式リリースノートでServer Function Loggingが正式機能として案内されました。開発中にServer Functionが呼ばれると、ターミナル上で関数名、引数、実行時間、定義ファイルが追えるようになっています。イメージとしては、今までブラックボックスだった「厨房」がガラス張りになった感覚です。結論として、Next.js 16.2以降は「再現しない障害」を開発環境で先に潰しやすくなりました

性能面の改善も見逃せません。公式では、開発起動が約400%高速化、レンダリングは約50%高速化、RSC payloadのデシリアライズは最大350%高速化と示されています。16.1比で約87%高速化の記載もあり、計測条件で数字は変わりますが、体感差が出るレベルなのは共通しています。つまり、調査そのものの待ち時間も短くなっているということです。

観点 16.1まで 16.2以降(開発) 本番
Server Function実行情報 追跡しづらい 関数名・引数・実行時間・ファイルが表示 直接は見えない
エラー表示 開発は詳細表示 開発は詳細表示 詳細は秘匿、digestのみ返る
初動調査の難易度 担当者依存 手順化しやすい ログ突合が必須
チーム共有 口頭依存になりがち ログスクショで共有しやすい Runbook前提で共有

ここで大事なのは、「開発で見える情報が増えた」ことと「本番で見えない情報がある」ことをセットで理解する点です。片方だけ理解すると、調査フローが崩れやすいです。

next.configで開発ログを見える化する設定

次に、Next.js Server Actions デバッグで最初に固定したい設定です。2026年3月25日更新のlogging公式ドキュメントでは、Server Function呼び出しログは開発時デフォルトONです。必要に応じてlogging.serverFunctions: falseでOFFにできます。さらにv16.2.0で追加されたbrowserToTerminalは、ブラウザ側のログをソース位置付きでターミナルへ流せるので、フロントとサーバーを行き来する調査がかなり楽になります。

/** @type {import('next').NextConfig} */
const nextConfig = {
  logging: {
    serverFunctions: true,
    browserToTerminal: 'warn',
  },
}

module.exports = nextConfig

僕のおすすめは、通常運用をbrowserToTerminal: 'warn'、障害再現時だけtrueへ上げる2段階運用です。常時trueだとノイズが増えるので、調査効率が落ちることがあります。逆にerror固定だと手掛かり不足になりやすいです。

  • 個人開発serverFunctions: true / browserToTerminal: 'warn' で十分です
  • チーム開発 – 役割別にプリセットを2つ用意すると引き継ぎしやすいです
  • 検証スプリント – 期間限定でbrowserToTerminal: trueにして原因を取り切ります

注意点は、引数ログに個人情報が混ざる可能性です。フォーム入力をそのまま流さず、マスキング関数を通してから出力する運用にすると安心です。設定テンプレは、通常時・調査時・停止時の3プリセットをREADMEに残すだけでも十分です。最後に、Server Actionsのタイムアウト検証ではページ側にexport const maxDuration = 5を置いて再現条件を固定すると、失敗パターンを切り分けやすいです。

Vercel本番500を10分で切り分けるRunbook

本番で500が出たら、感覚ではなく順番で処理します。2026年2月24日更新のVercel公式ガイドは9手順ありますが、初動10分なら次の4ステップで十分です。「status-code → request-id → deployment」の順で絞ると、迷子になりにくいです

  1. 直近1時間の500を抽出 – まず母数を把握します
  2. request-idで単一リクエストを追う – ノイズを消します
  3. deployment情報を確認 – どのデプロイから崩れたかを特定します
  4. 修正後5分で再検証 – 収束確認までを1セットで回します
# 1) 直近1時間の500を抽出
vercel logs --environment production --status-code 500 --json --since 1h

# 2) request-idを深掘り
vercel logs --request-id req_xxx --expand

# 3) デプロイ詳細を確認
vercel inspect https://your-deployment-url

# 4) 修正後の再確認
vercel logs --environment production --status-code 500 --json --since 5m

初動10分で必ず見る3点

  • status-code – 500だけでなく5xx全体の増減を見ます
  • request-id – 同一障害を1本の線で追えます
  • deployment – 直近変更と障害開始時刻を突き合わせます

2026年2月26日更新のFunction Logs仕様では、1出力=1ログ行、1行256KB、ISR時は1リクエストで複数ログが出る点が明記されています。つまり、ログ量だけで異常判定しないことが重要です。タイムスタンプとrequest-idを軸に揃えて見れば、数字の見え方に振り回されにくくなります。

digestを鍵にして原因を確定する手順

Next.jsの本番エラーで混乱しやすいのが、「画面には同じエラー文しか出ない」問題です。これは仕様で、error.tsxの公式ドキュメントにも、Server Component由来エラーは詳細をクライアントへ渡さずdigestを返すと書かれています。イメージとしては、digestは問い合わせ番号です。この番号をサーバーログ側と突き合わせると、同じ障害を確実に追えます。

// app/some-route/error.tsx
'use client'

export default function Error({ error, reset }) {
  console.error('digest:', error.digest)
  return (
    <div>
      <p>問題が発生しました。お問い合わせ時はdigestを共有してください。</p>
      <button onClick={() => reset()}>再試行</button>
    </div>
  )
}

さらに2026年3月31日更新のError Handlingガイドでは、Server Functionsの想定内エラーはthrowではなく戻り値で扱う方針が明確です。フォーム検証エラーまで例外扱いにすると、真の障害ログが埋もれます。まずはuseActionStateで業務エラーを返し、予期しない障害だけをthrowする2レーン運用にすると、digest突合の精度が上がります。

  • 想定内エラー – 戻り値で返してUIに表示します
  • 想定外エラー – throwしてdigestを発行し、ログで追跡します
  • ステータス確認error.tsx表示時でもHTTP 200になる構成があるので要確認です

「画面の見た目」と「実際のHTTPステータス」は必ず分けて確認する。この一手間で誤判定を防げます。

AGENTS.mdで調査漏れを防ぐチーム運用テンプレ

個人で速く調査できても、チームで再現できなければ運用は安定しません。そこで役立つのがAGENTS.mdです。Next.jsは2026年にAI Agentsガイドを公開し、node_modules/next/dist/docs/を先に参照する規約化を推奨しています。さらにNext.js 16.2 AI記事では、bundled docs方式が100% pass、skill方式が79% maxという比較も示されました。つまり、情報源を固定するだけでブレが減るということです。

# AGENTS.md(抜粋)
## Next.js Rules
- ALWAYS read docs before coding
- First source: node_modules/next/dist/docs/
- If production error: run vercel logs with status-code + request-id
- Record digest and deployment URL in incident note
非エンジニア部門と連携する場合は、技術用Runbookとは別に「連絡テンプレ」を1枚作るのがおすすめです。例えば「影響範囲」「暫定対応」「次回報告時刻」の3項目だけを固定すると、混乱が一気に減ります。

僕の現場では、このテンプレだけで初動の説明時間を約30分短縮できました。調査フローを定着させるには、障害発生時に使ったコマンド、request-id、digest、暫定対応を1つのincident noteへ残すのが効果的です。関連する運用基盤の考え方は、Mac mini運用コスト設計の記事でも整理しています。

この手順を持たずに1年運用したときの見えない損失

障害調査の型がないまま1年運用すると、開発スピードより先に信頼が削れます。ログはあるのに読めない、担当者がいないと止まる、説明が毎回バラバラになる、という状態が続くからです。この情報を知らないままだと、復旧時間だけでなく意思決定の速度まで落ちる可能性があります

  • 時間損失 – 同じ500を毎回ゼロから追うので、調査時間が雪だるま式に増えます
  • 機会損失 – リリース判断が遅れ、改善施策の実行時期を逃しやすくなります
  • 信頼損失 – 非エンジニアへ説明できず、チーム全体の不安が残りやすいです

この記事を書いている理由

僕がこのテーマを書いたのは、理屈より先に現場で何度も詰まったからです。結婚式Web招待状サービスを自作したときは、90日以上ログイン継続率を維持する中で、本番トラブルの初動速度が継続率に直結すると痛感しました。今も福祉領域のIT運用で、非エンジニア部門を含む調整を毎日行っています。さらにMac miniを24時間稼働させるNode.js/TypeScript運用を続ける中で、Runbookの有無で復旧品質が変わる場面を何度も見ました。僕自身がこの差を体験してきたからこそ、再現できる形で共有したいんです

次のアクション

今日やることは3つです。loggingを固定し、障害時はdigestとrequest-idを記録してAGENTS.mdへ転記してください。あわせて、再現コマンドとdeployment URLもincident noteに残すと次回の初動が速くなります。

今日からできるアクション

  • 設定loggingを固定
  • 記録digestとrequest-idを残す
  • 共有 – AGENTS.mdを更新