Summary
On Windows, Bun panics with panic(main thread): invalid enum value when the module resolver calls openDirAtWindowsNtPath on a path that goes through a junction (reparse point). This makes any project using bun install (which creates junctions in .bun/) crash immediately on certain Windows configurations.
Root Cause
RtlNtStatusToDosError is declared in src/windows.zig as returning Win32Error (an enum(u16)):
pub extern "ntdll" fn RtlNtStatusToDosError(win32.NTSTATUS) callconv(.winapi) Win32Error;
When NtCreateFile opens a junction directory and returns an NTSTATUS that maps to a Win32 error code not present in Bun's Win32Error enum, Zig's safety checks trigger a panic: invalid enum value.
In contrast, Zig's own standard library declares the same function as returning ULONG (u32) and does the safe conversion manually.
Reproduction
// Run from a directory with bunfig.toml that has preload = ["@opentui/solid/preload"]
// where @opentui/solid is a junction created by bun install
// → panic(main thread): invalid enum value
Also reproducible with the opencode project (sst/opencode) on Windows 11.
Stack Trace
sys.zig:1110 — openDirAtWindowsNtPath (origin point)
sys.zig:1178 — openDirAtWindowsT
sys.zig:1194 — openDirAtWindowsA
resolver.zig — dirInfoCachedMaybeLog → loadNodeModules → resolveAndAutoInstall
Crash URL: https://bun.report/1.3.12/wa1700fc11gGgkggC++uoKy0ixGg7oLkuh1Kqq9oNko2oN01o2KmlzlHwoz6Bi8skQyn4kQ2xk1G21muqBq4p5F+w/hGuwbyjM4svpzDCYKERNEL32.DLLut0LCSntdll.dll4/hjBA0eNrLzCtLzMlMUUjNK81VKEvMKU0FAEK2Bvo
Fix
Change the return type of RtlNtStatusToDosError from Win32Error to u32 and do safe enum conversion with fallback to MR_MID_NOT_FOUND (which is what the Windows API itself returns for unrecognised NTSTATUS values):
// src/windows.zig line 152
// Before:
pub extern "ntdll" fn RtlNtStatusToDosError(win32.NTSTATUS) callconv(.winapi) Win32Error;
// After:
pub extern "ntdll" fn RtlNtStatusToDosError(win32.NTSTATUS) callconv(.winapi) u32;
// fromNTStatus:
pub fn fromNTStatus(status: win32.NTSTATUS) Win32Error {
const code: u32 = RtlNtStatusToDosError(status);
if (code > std.math.maxInt(u16)) return .MR_MID_NOT_FOUND;
return std.meta.intToEnum(Win32Error, @as(u16, @intCast(code))) catch .MR_MID_NOT_FOUND;
}
PR with fix forthcoming.
Environment
- Windows 11 Pro (build 26200),
win11_dt
- CPU: x64 with SSE4.2, AVX, AVX2
- Bun v1.3.11 and v1.3.12 (both affected)
Summary
On Windows, Bun panics with
panic(main thread): invalid enum valuewhen the module resolver callsopenDirAtWindowsNtPathon a path that goes through a junction (reparse point). This makes any project usingbun install(which creates junctions in.bun/) crash immediately on certain Windows configurations.Root Cause
RtlNtStatusToDosErroris declared insrc/windows.zigas returningWin32Error(anenum(u16)):When
NtCreateFileopens a junction directory and returns an NTSTATUS that maps to a Win32 error code not present in Bun'sWin32Errorenum, Zig's safety checks trigger a panic:invalid enum value.In contrast, Zig's own standard library declares the same function as returning
ULONG(u32) and does the safe conversion manually.Reproduction
Also reproducible with the opencode project (sst/opencode) on Windows 11.
Stack Trace
Crash URL: https://bun.report/1.3.12/wa1700fc11gGgkggC++uoKy0ixGg7oLkuh1Kqq9oNko2oN01o2KmlzlHwoz6Bi8skQyn4kQ2xk1G21muqBq4p5F+w/hGuwbyjM4svpzDCYKERNEL32.DLLut0LCSntdll.dll4/hjBA0eNrLzCtLzMlMUUjNK81VKEvMKU0FAEK2Bvo
Fix
Change the return type of
RtlNtStatusToDosErrorfromWin32Errortou32and do safe enum conversion with fallback toMR_MID_NOT_FOUND(which is what the Windows API itself returns for unrecognised NTSTATUS values):PR with fix forthcoming.
Environment
win11_dt