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.
Bug
On Windows, the Feishu channel plugin crashes on every gateway startup with:
Both
mainandbot2Feishu 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 falseguard toshouldPreferNativeJiti(). This forces jiti to evaluate all dist.jschunks viavm.runInThisContextin 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"), thatimport()expression escapes from jiti's evaluated context to Node's native ESM loader. Node has never seenruntime-BAUYLedo.js(jiti loaded it, not Node), so it creates a second, independent module instance with its owncreatePluginRuntimeStoreclosure.Result:
setFeishuRuntime(api.runtime)writes to jiti's closure (during pluginregister())getFeishuRuntime()reads from Node ESM's closure (whenmonitorFeishuProviderruns)runtimeis stillnull→ throws"Feishu runtime not initialized"This only affects Windows because
shouldPreferNativeJitireturnstruefor.jsfiles on macOS/Linux, keeping both paths on the same native ESM module identity.Impact
createPluginRuntimeStore+ dynamicimport()in the dist chunk graphFix
Remove the
win32guard fromshouldPreferNativeJiti(). The actual Windows issue (backslash paths in jiti alias maps) was already solved bynormalizeJitiAliasTargetPath()in the same commit. ThetryNativedisable was unnecessary and broke module identity.