You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Different runtime behaviour of fs.realpath vs fs.promises.realpath is very confusing #37737
Have a project that was still using promisify(fs.realpath) and replace this with fs.promises.realpath to clean it up thinking the runtime behaviour will be the same. But in reality there is different behaviour: on Windows, subst drives will be resolved to their targets when realpath.native is used and left untouched with realpath.
How often does it reproduce? Is there a required condition?
Always when using subst drives on Windows. There are probably more differences.
What is the expected behavior?
That the fs API is in sync with the non promised variant. fs.promises.realpath should be a drop in replacement for promisify(fs.realpath) but not promisify(fs.realpath.native). There should be a fs.promises.realpath.native.
What do you see instead?
fs.promises.realpath behaves like promisify(fs.realpath.native)
FWIW the reason the implementations differ was explained here: #15485 (comment)
There are some variations from the base fs module (for instance, fs.async.realpath() uses the faster libuv realpath implementation rather than the slower js implementation.
Why?
Performance mainly. And lack of backwards compatibility concerns. The key reason we ended up having to revert back to the old realpath implementation is because changing broke existing code. We don't have that issue here. Also, if we kept the js implementation, we wouldn't really gain any performance advantages over simply doing util.promisify(fs.realpath) given the way it is implemented.
@jasnell FWIW going forward...this decision was unkind to users, I just got confused by this as well. I ran into a case where I'm going to have to promisify the non-native realpath to leave Windows short names like RUNNER~1 unchanged, since fs/promises doesn't provide a non-native version, and module keys in require.cache appear to not be native-realpathed.
Because the fsPromises method names match the fs method names, it's more reasonable to assume that they have the same behavior, than to assume they probably don't and we'd better RTFM just to make sure. Only a module name like fs2/promises would have given some clue that there might be differences in behavior.
Activity
aduh95 commentedon Mar 13, 2021
FWIW
fsPromises.realpathis documented as a promesified version offs.realpath.native(https://nodejs.org/api/fs.html#fs_fspromises_realpath_path_options).Do you want to open a PR?
bpasero commentedon Mar 13, 2021
Well, if there is agreement that
fs.promises.realpathbehaves likefs.realpaththen I can do a PR.aduh95 commentedon Mar 14, 2021
FWIW the reason the implementations differ was explained here: #15485 (comment)
jasnell commentedon Apr 30, 2021
This was an intentional decision. I'd be -1 to changing the current behavior of fs.promises.realpath
to matchfs.realpath`.StefanStojanovic commentedon Mar 28, 2025
Since this has been stale for some time, and the general opinion was against this change, I'll close this now. If needed, please reopen.
jedwards1211 commentedon Nov 28, 2025
@jasnell FWIW going forward...this decision was unkind to users, I just got confused by this as well. I ran into a case where I'm going to have to promisify the non-native
realpathto leave Windows short names likeRUNNER~1unchanged, sincefs/promisesdoesn't provide a non-native version, and module keys inrequire.cacheappear to not be native-realpathed.Because the
fsPromisesmethod names match thefsmethod names, it's more reasonable to assume that they have the same behavior, than to assume they probably don't and we'd better RTFM just to make sure. Only a module name likefs2/promiseswould have given some clue that there might be differences in behavior.jedwards1211 commentedon Nov 28, 2025
whether the native
realpathshould be treated as the default seems questionable because thefs.realpathdocs state thatfix: priečinok na namapovanom disku Windows prejde onboardingom