Skip to content

Feishu channel crash on Windows: dual jiti/ESM module instance splits runtime store #61614

@sanqiushu

Description

@sanqiushu

Bug

On Windows, the Feishu channel plugin crashes on every gateway startup with:

Error: Feishu runtime not initialized
    at extensions/feishu/src/monitor.account.ts:398

Both main and bot2 Feishu accounts fail, triggering exponential-backoff restart loops that never recover.

Root Cause

Commit 3a4b96b ("fix: normalize plugin SDK aliases on Windows") added a blanket if (process.platform === "win32") return false guard to shouldPreferNativeJiti(). This forces jiti to evaluate all dist .js chunks via vm.runInThisContext in its own internal cache, rather than delegating to Node's native ESM loader.

When the Feishu plugin later does a dynamic import("../../monitor-BnkfuO_x.js"), that import() expression escapes from jiti's evaluated context to Node's native ESM loader. Node has never seen runtime-BAUYLedo.js (jiti loaded it, not Node), so it creates a second, independent module instance with its own createPluginRuntimeStore closure.

Result:

  • setFeishuRuntime(api.runtime) writes to jiti's closure (during plugin register())
  • getFeishuRuntime() reads from Node ESM's closure (when monitorFeishuProvider runs)
  • The ESM closure's runtime is still null → throws "Feishu runtime not initialized"

This only affects Windows because shouldPreferNativeJiti returns true for .js files on macOS/Linux, keeping both paths on the same native ESM module identity.

Impact

  • All Feishu channel accounts fail to start on Windows
  • The restart loop runs indefinitely with exponential backoff (5s → 300s)
  • Affects any channel plugin that uses createPluginRuntimeStore + dynamic import() in the dist chunk graph

Fix

Remove the win32 guard from shouldPreferNativeJiti(). The actual Windows issue (backslash paths in jiti alias maps) was already solved by normalizeJitiAliasTargetPath() in the same commit. The tryNative disable was unnecessary and broke module identity.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions