Repository navigation
ENOENT error when reading root of subst drive on Windows #58970
Description
Activity
- addedwindowsIssues and PRs related to the Windows platform.Issues and PRs related to the Windows platform.libuvIssues and PRs related to the libuv dependency or the uv binding.Issues and PRs related to the libuv dependency or the uv binding.
on Jul 6, 2025 Hi, thanks for your report; just by doing some search in libuv, that's a known issue. I'm not a windows API programmer, at all. Not sure if there is much we can do from our side, for now, I'll just ping @nodejs/libuv; from what I see, I think it is easier to report this bug and suggest to your extension vendor that uses the extra
.char.I think it is because of
fs__capture_path, but I'm not sure. Again, it's a known issue, and many fs calls in windows "invokes"fs__capture_path, just likeuv_fs_realpath(the libuv call with caveats)Refs:
- Resolved path bypasses subst’d drives (uv_fs_realpath -inner calls fs__capture_path same as readdirSync-.)
- uv_fs_realpath doesn't respect DOS and subst mounts libuv/libuv#1877
- https://docs.libuv.org/en/v1.x/fs.html#c.uv_fs_realpath
- uv_fs_realpath doesn't respect DOS and subst mounts libuv/libuv#1877
@juanarbol Issue you pointed to libuv/libuv#1877 was closed as stale on Aug 10, 2019. While this error not reproduced with v20.19.3 (v20 first released Apr 18, 2023), nor with v21.7.3, but reproduced with v22.17.0. So this is more resent change in behavior.

That is as much, as I can investigate this (
echo y|cacls Subst /s:D:Pis to remove all permissions from directory to force error message):

As you can seefs.readdirSync("M:\\")in v22 case produce different error message:ENOENT: no such file or directory, scandir 'M:\\'instead ofEPERM: operation not permitted, scandir 'M:\'. Notice double backslash in the end of path.
As I mention in my comment to original issue, I think it is what causing the issue:

So in v22 (compared to v20) it was changed how paths normalized and
M:\now normalized toM:\\, which is incorrect behavior.I think issue is here:
Lines 1966 to 1987 in 1effb26
#ifdef _WIN32 // On Windows, some API functions accept paths with trailing slashes, // while others do not. This code checks if the input path ends with // a slash (either '/' or '\\') and, if so, ensures that the processed // path also ends with a trailing backslash ('\\'). bool slashCheck = false; if (path.ToStringView().ends_with("/") || path.ToStringView().ends_with("\\")) { slashCheck = true; } #endif ToNamespacedPath(env, &path); #ifdef _WIN32 if (slashCheck) { size_t new_length = path.length() + 1; path.AllocateSufficientStorage(new_length + 1); path.SetLengthAndZeroTerminate(new_length); path.out()[new_length - 1] = '\\'; } #endif
AsM:\ends with backslash, thenslashCheckwill betrue. And second#ifdef _WIN32seems to expect thatToNamespacedPathnewer return path, which ends with backslash (which likely incorrect forM:\as input), and adds backslash regardless ofpathcontent. That cause incorrect transformationM:\toM:\\.will you send a PR?
Not anytime soon. I do not really that familiar with C++, and currently do not have necessary tooling to build and test my changes.
Can confirm this IS a regression between node.js 20 and 22, as reported by users in VS Code (that recently updated to node.js 22).
With a
substdrive (subst T: C:\<some folder>)node.js 22:
C:\GitDevelopment\vscode>node Welcome to Node.js v22.17.0. Type ".help" for more information. > fs.readdirSync("T:\\") Uncaught Error: ENOENT: no such file or directory, scandir 'T:\\' at Object.readdirSync (node:fs:1583:26) { errno: -4058, code: 'ENOENT', syscall: 'scandir', path: 'T:\\\\' }node.js 20:
C:\Users\bpasero\Downloads>node Welcome to Node.js v20.9.0. Type ".help" for more information. > fs.readdirSync("T:\\") [ 'CHANGELOG.md', 'package.json', 'README.md', 'super', 'test.ps1', 'tsconfig.json', 'vsc-extension-quickstart.md', 'yarn.lock' ]Reacted by Mitherr and mag123cNo longer reproduced on v24.12.0 and v25.2.1.
Version
v24.3.0
Platform
Subsystem
No response
What steps will reproduce the bug?
How often does it reproduce? Is there a required condition?
Always
What is the expected behavior? Why is that the expected behavior?
No error should happens.
What do you see instead?
ENOENT: no such file or directory, scandir 'M:\\'
Additional information
Not program with Node.js myself. Have issue with this behavior with VS Code extension belav/csharpier#1637