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
ENOENT thrown when trying to create a file with an invalid filename #8987
Expected output: Some error message about the filename being invalid because it contains colons
Actual output:
Error: ENOENT: no such file or directory, open 'C:\temp\foo:bar:baz'
at Error (native)
at Object.fs.openSync (fs.js:640:18)
at Object.fs.writeFileSync (fs.js:1333:33)
at repl:1:4
at sigintHandlersWrap (vm.js:22:35)
at sigintHandlersWrap (vm.js:96:12)
at ContextifyScript.Script.runInThisContext (vm.js:21:12)
at REPLServer.defaultEval (repl.js:313:29)
at bound (domain.js:280:14)
at REPLServer.runBound [as eval] (domain.js:293:12)
Pretty sure that error codes comes straight from the Windows API, and it even seems consistent with macOS, so I'd lean towards leaving it as-is. Doing a check for filename validity on Windows is costly and should probably be done by the user.
So, just in case this is helpful: Colons are used by NTFS to name separate Alternate Data Streams, so if there’s a file named foo, creating foo:bar and writing to it (as an ADS) should work.
So it would seem to me that ENOENT would be the correct code for writing to foo:bar when foo doesn’t exist.
I’m not sure the overhead of checking for multiple colons would be worth it…
I believe it might be technically possible to provide a better error message since CreateFileW() on Windows probably sets the 'last error' code to ERROR_BAD_PATHNAME in such cases. From what I can tell, the original Windows-specific error code is stored by libuv in such a way that node should have access to it.
Reacted by Daniel Lo Nigro, Nathan Phillip Brink and Sindre Sorhus
So it would seem to me that ENOENT would be the correct code for writing to foo:bar when foo doesn’t exist.
Interesting, I didn't know that.
The same error message happens for other invalid characters though, such as question marks:
> fs.writeFileSync('C:\\temp\\foo??', 'fail')
Error: ENOENT: no such file or directory, open 'C:\temp\foo??'
at Error (native)
at Object.fs.openSync (fs.js:640:18)
at Object.fs.writeFileSync (fs.js:1333:33)
at repl:1:4
The issue here is that libuv maps ERROR_INVALID_NAME to UV_ENOENThere. This particular mapping was added by @piscisaureus way back in 2012.
The question is what it should map to instead. Would UV_EINVAL be better? Understandably, libuv doesn't have a dedicated error code for an invalid file name since Linux doesn't have invalid filenames.
You could change it (major version), but before you do so, do some research into what different "libc" implementations do on windows - at least try what error the open() call in msvcrt produces when you try to create a file with an invalid name, and try cygwin too.
A / is a invalid character in a filename on all likely all Linux filesystems. The returned error code depends on the location of the / in the filename:
fs.writeFile("invalid/")
// Error: EISDIR: illegal operation on a directory, open 'invalid/'
> fs.writeFile("invalid/file")
// Error: ENOENT: no such file or directory, open 'invalid/file'
There's been no activity on this and it's been blocked indefinitely pending the update to libuv 2.x. Keeping the issue open does not benefit anyone but we also don't want to forget about it. I've added it to a Futures project board so it doesn't get lost.
Activity
silverwind commentedon Oct 9, 2016
Pretty sure that error codes comes straight from the Windows API, and it even seems consistent with macOS, so I'd lean towards leaving it as-is. Doing a check for filename validity on Windows is costly and should probably be done by the user.
Daniel15 commentedon Oct 9, 2016
Are you sure? I tried the equivalent in C#:
And got a better error message:
Or:
I didn't try raw Win32 API calls though.
addaleax commentedon Oct 9, 2016
So, just in case this is helpful: Colons are used by NTFS to name separate Alternate Data Streams, so if there’s a file named
foo, creatingfoo:barand writing to it (as an ADS) should work.So it would seem to me that ENOENT would be the correct code for writing to
foo:barwhenfoodoesn’t exist.I’m not sure the overhead of checking for multiple colons would be worth it…
mscdex commentedon Oct 9, 2016
I believe it might be technically possible to provide a better error message since
CreateFileW()on Windows probably sets the 'last error' code toERROR_BAD_PATHNAMEin such cases. From what I can tell, the original Windows-specific error code is stored by libuv in such a way that node should have access to it.Daniel15 commentedon Oct 9, 2016
Interesting, I didn't know that.
The same error message happens for other invalid characters though, such as question marks:
seishun commentedon Oct 13, 2016
The issue here is that libuv maps
ERROR_INVALID_NAMEtoUV_ENOENThere. This particular mapping was added by @piscisaureus way back in 2012.The question is what it should map to instead. Would
UV_EINVALbe better? Understandably, libuv doesn't have a dedicated error code for an invalid file name since Linux doesn't have invalid filenames.piscisaureus commentedon Oct 13, 2016
You could change it (major version), but before you do so, do some research into what different "libc" implementations do on windows - at least try what error the open() call in msvcrt produces when you try to create a file with an invalid name, and try cygwin too.
silverwind commentedon Oct 13, 2016
A
/is a invalid character in a filename on all likely all Linux filesystems. The returned error code depends on the location of the/in the filename:seishun commentedon Oct 13, 2016
@piscisaureus
Good idea. I assume you meant fopen, not open.
fopen("foo??", "w")setserrnotoEINVALin both CRT and MSYS2.@silverwind
In both of your examples,
/is interpreted as a path separator. I don't think it's even possible to make Linux interpret it as part of the file name.paulbjensen commentedon Oct 19, 2016
Thanks for reporting this issue, I had no idea that : were invalid file name characters in Windows, been debugging an Electron app for a bit now.
win: map ERROR_INVALID_NAME to UV_EINVAL
Trott commentedon Jul 15, 2017
Should this issue remain open?
seishun commentedon Jul 15, 2017
It's going to remain an issue until libuv is upgraded to 2.x.
test: add test-fs-writeFileSync-invalid-windows
jasnell commentedon Jun 25, 2020
There's been no activity on this and it's been blocked indefinitely pending the update to libuv 2.x. Keeping the issue open does not benefit anyone but we also don't want to forget about it. I've added it to a Futures project board so it doesn't get lost.