Node.js 18 以降では、fetch が 標準API として組み込まれました。これにより、ブラウザとほぼ同等の Fetch API が Node.js でも使えるようになりましたが、その一方で次のようなエラーに遭遇するケースが増えています。
TypeError: Request with GET/HEAD method cannot have body
「今まで動いていたコードなのに、Node を上げたら突然エラーが出た」という人も多いはずです。本記事では、このエラーが発生する根本的な理由と、実務で使える回避策を整理します。
このエラーが発生する背景
Node.js 18 以降の fetch は仕様に厳密
Node.js 18 から導入された fetch は、内部的に WHATWG Fetch Standard に準拠しています。これはブラウザの fetch と同じ仕様であり、HTTP のルールを厳密に守ります。
その結果、以下の制約がそのまま適用されます。
- GET / HEAD メソッドでは body を持てない
- body を指定した時点で例外を投げる
これは Node 独自の制限ではなく、HTTP仕様上の正当な挙動です。
過去のライブラリでは黙認されていた
以前よく使われていた以下のようなライブラリでは、GET + body が暗黙的に許容されていました。
- node-fetch(古いバージョン)
- request
- axios(一部の設定)
そのため「GET で body を送る」というアンチパターンが、実務コードに残っていることが少なくありません。
よくあるエラー例
GET に body を指定している
以下のコードは Node.js 18 以降ではエラーになります。
await fetch('https://api.example.com/users', {
method: 'GET',
body: JSON.stringify({ id: 1 }),
})
ブラウザでも同様に、この書き方は仕様違反です。
なぜ GET で body を送れないのか
HTTP仕様上の理由
HTTP/1.1 および Fetch Standard では、GET リクエストは次の性質を持ちます。
- リソースの取得が目的
- 副作用を持たない
- キャッシュ可能
- URL(クエリ)によって完全に表現される
このため、body を許可すると以下の問題が発生します。
- キャッシュのキーに含まれない
- プロキシやCDNが無視する
- サーバー・クライアント間で挙動が不一致になる
これを防ぐため、Fetch API では 明示的に禁止されています。
実務での回避策
1. クエリパラメータに変換する(最優先)
最も正しい解決方法
GET を使いたい場合は、body ではなく URL クエリに変換します。
const params = new URLSearchParams({ id: '1' })
await fetch(`https://api.example.com/users?${params}`)
向いているケース
- 検索条件
- ID指定
- フィルタ条件
- キャッシュさせたいAPI
2. POST に切り替える
データを送るなら POST が正解
body を送りたい場合は、HTTPメソッド自体を見直します。
await fetch('https://api.example.com/users/search', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ id: 1 }),
})
判断基準
- データ量が多い
- 検索条件が複雑
- キャッシュ不要
この場合、エンドポイント設計を分けるのがベストプラクティスです。
3. HEAD メソッドでも同様に注意
HEAD も body は送れない
HEAD は GET と同様に body を持てません。
await fetch(url, {
method: 'HEAD',
body: 'xxx', // 同じエラーになる
})
レスポンスヘッダだけが欲しい用途に限定して使いましょう。
Node.js fetch 特有の注意点
axios からの移行時にハマりやすい
axios では次のような書き方が可能でした。
axios.get('/api', { data: { id: 1 } })
これをそのまま fetch に置き換えるとエラーになります。
fetch 移行時のチェックポイント
- GET/HEAD に body を渡していないか
- 検索APIが POST の方が適切ではないか
- クエリ化できる設計になっているか
エラーを回避するための設計指針
API設計側で意識すべきポイント
- GET: クエリのみ、キャッシュ前提
- POST: body を使った検索・処理
- PUT/PATCH: 更新
- DELETE: 削除
Node.js の fetch は「仕様に厳しい」だけで、間違った設計を教えてくれる存在とも言えます。
まとめ
Node.js の fetch で発生する
「Request with GET/HEAD method cannot have body」エラーは、バグではありません。
ポイント整理
- Node.js 18 以降の fetch は仕様準拠
- GET / HEAD に body は送れない
- クエリ or POST に設計を切り替えるのが正解
- 古いコード・axios 移行時は特に注意
このエラーに遭遇したら、「回避する」のではなく API設計を見直すサイン として捉えるのが、長期的には最も安全です。

