Windows MAX_PATH limitation causes subpath imports to fail.
The issue involves subpath imports failing on Windows when the path exceeds the MAX_PATH limit. The problem is reproducible with a provided test case, but the solution may require understanding Windows file system limitations and Node.js module resolution. The scope is somewhat clear, but the fix might involve cross-cutting changes.
v24.12.0
Microsoft Windows NT 10.0.26200.0 x64
No response
I ran into this while running pnpm dev in a project with a deep node_modules path:
TypeError: Package import specifier "#module-sync-enabled" is not defined imported from
C:\Users\...\node_modules\.pnpm\@[email protected]_...\@react-router\dev\module-sync-enabled\index.mjs
Minimal repro — save as test.mjs and run with node test.mjs on Windows (with LongPathsEnabled):
import fs from "node:fs";
import { createRequire } from "node:module";
import path from "node:path";
// \\?\ prefix bypasses MAX_PATH limit for Win32 file APIs
const lp = (p) => "\\\\?\\" + p;
const ok = (fn) => {
try { fn(); return "OK"; }
catch (e) { console.error(e); return "FAIL"; }
};
const MAX = 259; // MAX_PATH (260) minus null terminator
const cwd = process.cwd();
const fixedLen = cwd.length + 2 + "package.json".length;
const results = {};
for (const target of [MAX, MAX + 1]) {
const dir = path.join(cwd, "a".repeat(target - fixedLen));
const dep = path.join(dir, "node_modules", "dep");
fs.mkdirSync(lp(dep), { recursive: true });
fs.writeFileSync(
lp(path.join(dir, "package.json")),
JSON.stringify({ imports: { "#foo": "./foo.mjs" } }),
);
fs.writeFileSync(lp(path.join(dir, "foo.mjs")), "export default 1\n");
fs.writeFileSync(
lp(path.join(dep, "package.json")),
JSON.stringify({ name: "dep", exports: { ".": "./index.mjs" } }),
);
fs.writeFileSync(lp(path.join(dep, "index.mjs")), "export default 1\n");
const { resolve } = createRequire(path.join(dir, "_.mjs"));
results[`${target} chars`] = {
"fs.access": ok(() => fs.accessSync(lp(path.join(dir, "package.json")))),
'resolve("dep")': ok(() => resolve("dep")),
'resolve("#foo")': ok(() => resolve("#foo")),
};
fs.rmSync(lp(dir), { recursive: true, force: true });
}
console.table(results);
Claim this issue to let others know you're working on it. You'll earn 20 points when you complete it!