🤯

wrangler 4.13.2 で @opensearch-project/opensearch 3.5.1 を使うとエラーになって

に公開

ふとしです。

対処

にっちもさっちもいかなく、結局 fetch で生リクエストしました。

原因

対処は 👆 というどうしようもない方法を取ったのですが、調査中同じエラーで困っている記事を見つけられなかったので、とりあえずエラーや原因をメモっておきます。

対処法や、対処されたという情報をお持ちの方は、ご一報いただけると幸いです。

直面したエラー

bulk でデータの挿入を行おうとすると以下のエラーになりました。

✘ [ERROR] TypeError: The "string" argument must be of type string or an instance of Buffer or ArrayBuffer. Received an instance of Array

      at Buffer.byteLength (node-internal:internal_buffer:300:15)
以下略

メソッドに渡す型などは合っており、ライブラリのほうが間違っているのだろうなと思い、スタックトレースをもとにコードを追いました。

https://github.com/opensearch-project/opensearch-js/blob/b85602058649d94fcde6ffc8d87983313b139943/lib/Transport.js#L530

上記のように長さを測っていますが、求められている方は配列などなので、上流で変換が行われているのだろうと遡ってみます。

https://github.com/opensearch-project/opensearch-js/blob/b85602058649d94fcde6ffc8d87983313b139943/lib/Transport.js#L470-L480

すると shouldSerialize という関数の結果によりシリアライズを行う部分を発見できました。これがなんらかの原因で false になっている可能性が高い。

https://github.com/opensearch-project/opensearch-js/blob/b85602058649d94fcde6ffc8d87983313b139943/lib/Transport.js#L669-L673

実装は上のようになっており Buffer.isBuffer(obj) === false の結果がおかしい気配がぷんぷんしますね。というわけで、bulkBody となる値を Buffer.isBuffer(bulkBody) してみると

undefined

燦然と輝く上の値が得られました。

boolean が求められているのに undefined が返っているので、例外となってしまったわけですね。

たぶん原因の原因

そもそも @opensearch-project/opensearch

✘ [ERROR] Build failed with 20 errors:

  ✘ [ERROR] Could not resolve "events"
  
      node_modules/@opensearch-project/opensearch/lib/Client.js:32:33:
        32 │ const { EventEmitter } = require('events');
           ╵                                  ~~~~~~~~
  
    The package "events" wasn't found on the file system but is built into node.
    - Add the "nodejs_compat" compatibility flag to your project.
以下略

というエラーが出て

"compatibility_flags": ["nodejs_compat"]

を追加しないとビルドさえできなかったのでした。

これで挿入?された Buffer の実装がおかしく、エラーになっているのではないかなあというのがとりあえずの結論であります。

おわりに

まぁでも生リクエストもそんなに複雑怪奇な構造じゃないので fetch でシュッと書けて良かったです。

Discussion