Node + tsx “__name is not a function” 當機

摘要

透過 Node 搭配 tsx 執行 OpenClaw 時,啟動階段就會失敗:

[openclaw] Failed to start CLI: TypeError: __name is not a function
    at createSubsystemLogger (.../src/logging/subsystem.ts:203:25)
    at .../src/agents/auth-profiles/constants.ts:25:20

這個問題在開發腳本從 Bun 切換到 tsx 之後出現(commit 2871657e,2026-01-06)。相同的執行路徑在 Bun 下運作正常。

環境

  • Node:v25.x(在 v25.3.0 上觀察到)
  • tsx:4.21.0
  • OS:macOS(其他執行 Node 25 的平台也可能重現)

重現步驟(僅限 Node)

# 在 repo 根目錄
node --version
pnpm install
node --import tsx src/entry.ts status

在 repo 中的最小重現

node --import tsx scripts/repro/tsx-name-repro.ts

Node 版本檢查

  • Node 25.3.0:失敗
  • Node 22.22.0(Homebrew node@22):失敗
  • Node 24:尚未安裝;需要驗證

筆記 / 假說

  • tsx 使用 esbuild 轉換 TS/ESM。esbuild 的 keepNames 會產生 __name 輔助函式,並將函式定義包裝為 __name(...)
  • 當機訊息顯示 __name 存在但在執行期間不是函式,這表示在 Node 25 的載入器路徑中,該輔助函式遺失或被覆寫了。
  • 類似的 __name 輔助函式問題在其他 esbuild 使用者中也有報告,通常是輔助函式遺失或被重寫所致。

迴歸歷史

  • 2871657e(2026-01-06):腳本從 Bun 改為 tsx,讓 Bun 變成選用。
  • 在此之前(Bun 路徑),openclaw statusgateway:watch 都正常運作。

解決方法

  • 開發腳本改回使用 Bun(目前的暫時回退)。

  • 使用 Node + tsc watch,然後執行編譯後的產出:

    pnpm exec tsc --watch --preserveWatchOutput
    node --watch openclaw.mjs status
  • 已在本機確認:pnpm exec tsc -p tsconfig.json + node openclaw.mjs status 在 Node 25 上正常運作。

  • 如果可以的話,在 TS 載入器中停用 esbuild keepNames(防止 __name 輔助函式注入);tsx 目前不提供此選項。

  • 在 Node LTS(22/24)上測試 tsx,確認是否為 Node 25 特有的問題。

參考資料

後續步驟

  • 在 Node 22/24 上重現以確認是否為 Node 25 迴歸。
  • 測試 tsx 的 nightly 版本,或在已知迴歸存在時固定到較早版本。
  • 如果在 Node LTS 上也能重現,向上游提交包含 __name 堆疊追蹤的最小重現。