newmanがNode.js 22以降で「global is not defined」になる原因と直し方
CI の Node.js を 22 以降に上げたら、newman のシナリオが 1 本も動かなくなっていませんか?
エラーは Error: global is not defined で、リクエストを 1 つも送らないうちに止まります。
スタックトレースには newman もコレクションのファイル名も出てこないので、シナリオの中身を疑いやすいエラーです。
壊れるのは newman 6.2.0 だけで、6.2.1 以降なら直ります。
最小構成の再現スクリプトを Node.js 20 / 22 / 24 で動かし、各版の依存を npm のレジストリと突き合わせて確かめました。
この記事では、原因と直し方に加えて、overrides で直すときの落とし穴(isEmpty is not a function)もまとめます。
症状: リクエストを送る前に global is not defined で止まる
newman 6.2.0 を Node.js 22 で動かすと、次のエラーで止まります。
node:internal/event_target:1118
process.nextTick(() => { throw err; });
^
Error: global is not defined
at lib/core/connect.js (node:internal/deps/undici/undici:2593:5)
at __require (node:internal/deps/undici/undici:6:50)
at lib/dispatcher/client.js (node:internal/deps/undici/undici:7827:26)
...
at lib/global.js (node:internal/deps/undici/undici:8523:17)スタックトレースに出てくるのは Node.js に内蔵されている undici(HTTP クライアント)で、newman やコレクションのファイル名は出てきません。
私も最初は、シナリオの中身や認証まわりを疑いました。
シナリオが原因かどうかを最小構成で切り分ける
pre-request スクリプトを 1 つだけ持つコレクションを newman で実行すると、シナリオの中身と切り離して確かめられます。
const newman = require('newman');
console.log('node', process.version,
'newman', require('newman/package.json').version,
'postman-runtime', require('postman-runtime/package.json').version);
newman.run({
collection: {
info: { name: 'repro', schema: 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json' },
item: [{
name: 'req',
event: [{ listen: 'prerequest', script: { exec: ['console.log("prerequest script ran")'] } }],
// 宛先はわざと存在しないものにしている(スクリプトが動くかだけを見る)
request: { method: 'GET', url: 'http://127.0.0.1:9/' }
}]
},
reporters: 'cli'
}, (err) => { console.log('newman done, err =', err && err.message); });スクリプトが動けば prerequest script ran と表示され、その後に接続エラーが出て newman が最後まで終わります。
newman 6.2.0 で試した結果は次のとおりです。
| Node.js | newman 6.2.0 の結果 |
|---|---|
| 20.20.2 | スクリプトが動き、最後まで終わる |
| 22.22.1 | global is not defined で止まる |
シナリオの中身とは関係なく、newman がスクリプトを実行する部分の問題だと分かります。
newman の GitHub にも同じ報告があり(postmanlabs/newman#3267)、メンテナーは Node.js 22.3.0 以降で再現するとコメントしています。
原因: newman 6.2.0 だけが新しい postman-sandbox を使っている
newman は、スクリプトの実行を postman-runtime → postman-sandbox という依存に任せています。
そして newman は、postman-runtime のバージョンを完全一致で固定しています。
各版の依存は npm view で確認できます。
npm view newman@6.2.2 dependencies.postman-runtime
npm view postman-runtime@7.39.1 dependencies.postman-sandboxnewman の版ごとに並べると、次のとおりです。
| newman | 公開日 | postman-runtime | postman-sandbox | Node.js 22 以降 |
|---|---|---|---|---|
| 6.1.3 | 2024-06-10 | 7.39.0 | 4.7.1 | 動く(Issue の報告) |
| 6.2.0 | 2024-08-16 | 7.41.2 | 5.1.1 | 落ちる |
| 6.2.1 | 2024-08-20 | 7.39.1 | 4.7.1 | 動く(Issue の報告) |
| 6.2.2 | 2026-01-16 | 7.39.1 | 4.7.1 | 動く(22.23.3 / 24.21.0 で確認) |
postman-sandbox 5.x を使うのは 6.2.0 だけです。
6.2.1 では 4.7.1 に戻されていて、公開は 6.2.0 のわずか 4 日後です。
問題を受けて、依存を戻したのだと思われます。
なぜ global がないのか(推測を含む)
node_modules の中を読んで確認できたのは、次の 2 点です。
- postman-sandbox 5.1.1 が使う
uvm3.0.0 は、Node.js ではスクリプトを Worker スレッド(worker_threads)の中で実行する - postman-sandbox は Worker の起動時に、許可リストにないグローバル変数をすべて削除している(
lib/sandbox/index.js)
ここからは推測です。
Node.js 22 では、この Worker の中で内蔵の undici が読み込まれ、その時点で参照する global がすでに削除されているため落ちているのだと考えています。
なぜ Node.js 22 で Worker の中の undici が読み込まれるようになったのかまでは、確かめられていません。
直し方: newman を 6.2.1 以降に上げる
いちばん簡単な直し方は、newman を上げることです。
npm install newman@6.2.2上の最小構成を newman 6.2.2 で実行すると、Node.js 22.23.3 でも 24.21.0 でも、スクリプトが動いて最後まで終わりました。
node v22.23.3 newman 6.2.2 postman-runtime 7.39.1
newman
repro
→ req
┌
│ 'prerequest script ran'
└
GET http://127.0.0.1:9/ [errored]
connect ECONNREFUSED 127.0.0.1:9ECONNREFUSED は、宛先をわざと存在しないものにしているためです。
package.json の書き方によって、上げ方が変わります。
"newman": "6.2.0"のように完全一致で固定している → ここを書き換える^6.2.0の指定 →package-lock.jsonを更新すれば 6.2.2 が入る
なお Node.js 24 では、newman 本体から [DEP0176] DeprecationWarning: fs.F_OK is deprecated という警告が出ますが、実行は止まりません。
最新の 6.2.2 のほうが依存が古いのはなぜか
依存を調べると、最新の 6.2.2 は、6.2.0 より古い postman-runtime に固定されています。
これを見て「上げても直らない」と判断しやすいのですが、私も実際にそう判断して遠回りしました。
そのときの考えは、次のとおりです。
- 今使っている 6.2.0 は postman-runtime 7.41.2 に固定されている
- 最新の 6.2.2 は、それよりさらに古い 7.39.1 に固定されている
- だから newman を上げても新しい postman-runtime は入らず、直らないだろう
そして、newman は 6.2.0 のまま、overrides で postman-runtime だけを最新版に差し替える方法を選びました。
しかし実際は、壊れていたのは「新しすぎる」6.2.0 の依存のほうでした。
6.2.2 が古い版に固定されているのは、問題が起きる前の版に戻したからです。
最小構成のスクリプトは手元にあったので、6.2.2 を一度動かしていれば数分で分かったはずです。
依存のバージョンの大小では判断せず、候補の版で最小構成を実際に動かして確かめてください。
もう 1 つの直し方: overrides で postman-runtime を差し替える
遠回りではありましたが、overrides による方法も動作はしています。
{
"dependencies": {
"newman": "6.2.0"
},
"overrides": {
"postman-runtime": "7.56.1"
}
}これで、newman 6.2.0 → postman-runtime 7.56.1 → postman-sandbox 6.7.4 という構成になります。
最小構成は Node.js 20 / 22 / 24 のすべてで動き、実際のシナリオも Node.js 24 で成功しました。
postman-runtime 7.56.1 は engines で Node.js 18 以上を要求しているので、それより古い Node.js では使えません。
落とし穴: newman 6.2.2 と組み合わせると isEmpty is not a function
注意したいのは、newman 6.2.2 に上げたうえで、この overrides を残すと別のエラーで落ちることです。
event.script.isEmpty is not a functionnewman 6.2.2 は postman-collection を 4.4.0 に固定していて、6.2.0 の 4.5.0 より古くなります。
一方、postman-runtime 7.56.1 は postman-collection 5.3.1 を前提にしています。
newman が作った古い postman-collection のオブジェクトを新しい postman-runtime が受け取り、古い版にないメソッドを呼んでいるのだと思われます(推測です)。
newman を上げるなら overrides は外す、overrides を使うなら newman は 6.2.0 のまま、のどちらかに揃えてください。
どちらの直し方を選ぶか
| 対処 | 良いところ | 気になるところ |
|---|---|---|
| newman を 6.2.2 に上げる | 変更が 1 行で済む。newman が想定した組み合わせのまま | postman-sandbox は 6.2.0 より前の 4.7.1 のまま |
| overrides で postman-runtime を差し替える | スクリプト実行まわりが新しい版になる | newman が想定していない組み合わせ。newman を更新するたびに見直しが要る |
まずは newman を 6.2.2 に上げるのが素直です。
どちらの場合も古い依存が多く残るので、npm audit の結果は別途確認してください。
newman 6.2.2 だけを新しく入れた状態でも、critical を含む脆弱性が報告されました。
もう 1 つ確認したいのが、@postman/tunnel-agent の固定です。
2025 年 11 月の npm サプライチェーン攻撃への対処で、overrides でこのパッケージを 0.6.4 に固定している場合は注意してください。
newman 6.2.2 が使う postman-request も、overrides で入る postman-runtime 7.56.1 が使う postman-request も、0.6.8 以上を前提にしています。
固定を残すと 0.6.4 が入ったままになり、npm ls にも警告は出ません。
正規の 0.6.8 が出た経緯と固定の外し方は、npm サプライチェーン攻撃で実際に行った影響調査と復旧手順に追記しています。
まとめ
- newman が Node.js 22 以降で
Error: global is not definedになるのは、newman 6.2.0 だけの問題 - 6.2.0 だけが postman-sandbox 5.x を使っており、6.2.1 で 4.7.1 に戻されている
- 直し方は newman を 6.2.1 以降(6.2.2)に上げるだけ。Node.js 22 / 24 で動くことを確認した
overridesで postman-runtime を差し替える方法も動くが、newman 6.2.2 と組み合わせるとisEmpty is not a functionで落ちる- 「新しい版が古い依存に固定されている」ときは、問題が出る前に戻しただけかもしれない。大小で判断せず、実際に動かして確かめる
依存を調べていると、つい「新しいほうが直っている」と考えてしまいます。
しかし newman では、新しい版のほうが古い依存に戻して直していました。
再現スクリプトを作ったら、仮説を立てる前に候補の版で一度動かしてみるのが近道です。
newman でコレクションをまとめて実行する基本の使い方は、Postman と Newman を使って複数の API を連続して実行させるで紹介しています。
