newmanがNode.js 22以降で「global is not defined」になる原因と直し方

saratogax
記事内に商品プロモーションを含む場合があります

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.jsnewman 6.2.0 の結果
20.20.2スクリプトが動き、最後まで終わる
22.22.1global 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-sandbox

newman の版ごとに並べると、次のとおりです。

newman公開日postman-runtimepostman-sandboxNode.js 22 以降
6.1.32024-06-107.39.04.7.1動く(Issue の報告)
6.2.02024-08-167.41.25.1.1落ちる
6.2.12024-08-207.39.14.7.1動く(Issue の報告)
6.2.22026-01-167.39.14.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 が使う uvm 3.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:9

ECONNREFUSED は、宛先をわざと存在しないものにしているためです。

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 に固定されています。

これを見て「上げても直らない」と判断しやすいのですが、私も実際にそう判断して遠回りしました。

そのときの考えは、次のとおりです。

  1. 今使っている 6.2.0 は postman-runtime 7.41.2 に固定されている
  2. 最新の 6.2.2 は、それよりさらに古い 7.39.1 に固定されている
  3. だから 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 function

newman 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 を連続して実行させるで紹介しています。

ABOUT ME
saratoga
saratoga
フリーランスエンジニア
仕事にも趣味にも IT を駆使するフリーランスエンジニア。技術的な TIPS や日々の生活の中で深堀りしてみたくなったことを備忘録として残していきます。
記事URLをコピーしました