Skip to content

Express.jsでのpathToRegexpエラー:Missing parameter nameの解決法

問題の概要

Express.js アプリケーションをデプロイ後(特に Render.com)、以下のエラーが発生する場合があります:

shell
TypeError: Missing parameter name at 1: https://git.new/pathToRegexpError
    at name (path-to-regexp/dist/index.js:85:19)
    at lexer (path-to-regexp/dist/index.js:103:27)
    ...
Node.js v20.15.1

この問題は Express 5.0+にアップグレードした際、ルーティング構文の変更に起因します。

根本原因:Express 5のルーティング変更点

Express 5から内部で使用されるpath-to-regexpライブラリがv8.0へ更新され、ワイルドカード(*)の扱いが変更されました:

Expressバージョン*の動作
v4.xワイルドカードとして任意のパスをキャッチ
v5.0+パラメータ名として扱われる(:paramと同じ挙動)

典型的な非互換コード例

js
// Express 4では有効だが5ではエラーになる
app.get('/*', handlerFunction);
app.use('*', middlewareFunction);

推奨解決方法:正規表現を使用する

1. 正規表現によるパスマッチング

js
// 変更前(エラーが発生)
app.get('/*', handlerFunction);

// 変更後(正規表現を使用)
app.get(/(.*)/, (req, res) => {
  // req.params[0] にマッチしたパスが格納される
  console.log('Matched path:', req.params[0]); 
});

2. キャッチオールルーティングの修正

js
// ミドルウェアでの使用例
// 変更前
app.use('*', corsMiddleware);

// 変更後
app.use(/(.*)/, corsMiddleware);

代替案:Expressの命名パラメータ構文を使用

公式ドキュメント推奨形式

js
// /* の代わりに /{*splat} を利用
app.get('/{*splat}', (req, res) => {
  // req.params.splat でパスを取得
  console.log('Captured path:', req.params.splat);
});

パラメータ名の選択

splatは慣例的に使用されますが、任意の有効な変数名で代用可能です:

js
app.get('/{*anyPath}', controllerFunction);

緊急対処法:Expressを4.xにダウングレード

APIの互換性が必要な場合の一時的な解決策:

shell
# 1. package-lock.jsonを削除
rm package-lock.json

# 2. Express 4を明示的にインストール
npm install express@4.20.0

# 3. 依存関係を再構築
npm install

ダウングレードの注意点

  1. npm auditでセキュリティ警告が表示される可能性あり
  2. Express 5対応アップデート時に再発するリスク
  3. 恒久策としてはルーティング修正を推奨

変更点の技術的背景

path-to-regexp@8.0の主な変更点:

  • 無名パラメータ(例::*)禁止
  • 名前付き正規表現グループ必須化
  • ?,+などの特殊記号の意味変更
yaml
# 変更前: 任意のパスにマッチ
/* → v4では動作

# 変更後: 名前と正規表現が必要
/{*splat} → v5必須書式

補足アドバイス

  1. 全ルートの一括検索
    エラー発生箇所特定に:

    bash
    grep -r "app\.\(get\|use\)([\"'][^)]*\*" src/
  2. 公式変更履歴の確認

まとめ

状況対応方法
新規開発中/(.*)/ 正規表現を使用
既存プロジェクト移行/{*splat} 構文へ変更
緊急復旧必要Express 4.xにダウングレード

ベストプラクティスは正規表現か名前付きパラメータへの移行です。変更は最低1時間程度で完了可能で、将来的なバージョンアップ時の互換性も確保できます。