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로 전환한 후 발생했습니다 (커밋 2871657e, 2026-01-06). 동일한 런타임 경로가 Bun에서는 작동했습니다.

환경

  • Node: v25.x (v25.3.0에서 확인)
  • tsx: 4.21.0
  • OS: macOS (Node 25를 실행하는 다른 플랫폼에서도 재현 가능성 있음)

재현 (Node 전용)

# 저장소 루트에서
node --version
pnpm install
node --import tsx src/entry.ts status

저장소 내 최소 재현

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 로더 경로에서 해당 모듈에 대한 헬퍼가 누락되거나 덮어씌워졌음을 의미합니다.
  • 다른 esbuild 사용자에서도 헬퍼가 누락되거나 다시 작성될 때 유사한 __name 헬퍼 문제가 보고되었습니다.

회귀 이력

  • 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 스택 트레이스와 함께 최소 재현을 업스트림에 제출합니다.