Skip to content

Windows: panic 'invalid enum value' when resolving node_modules junctions via RtlNtStatusToDosError #29158

@0okay

Description

@0okay

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions