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
Corrupt a file at a low level, I think this needs to be down to the NTFS level.
Begin an operation that causes node to invoke lstat on one of the corrupted files. For me specifically, this was a yarn operation.
How often does it reproduce? Is there a required condition?
Intermittently (depends on file corruption), or constantly if the files remain corrupted. Because of Issue #34817, there is no useful stacktrace, so it's hard to say what operation specifically invokes the failing call.
What is the expected behavior?
Show the error code so a developer can debug the issue.
As someone who's only mildly familiar with libuv, and barely familiar with node's C++ architecture, this was very hard to understand.
The first clue I had came while trying to figure out what the error was. I had to trace it in procmon to do that. The offending event was an IRP_MJ_CREATE (generated by NtCreateFile up the stack) that failed with a result that procmon called FILE CORRUPT. I believe this refers to a 0xC0000102/STATUS_FILE_CORRUPT_ERROR NTSTATUS code. It would be useful to show this, but I'll come back to that later.
As best as I can tell, the node entry point/bridge from js to native for lstat is LStat, here.
The reason I'm filing this bug is that it looks like libuv has a way to get the underlying error code out (through SET_REQ_WIN32_ERROR) even if it's not a known error code. I think that uv_fs_lstat returns the translated error, but also stuffs the system errno in the private DWORDreq->sys_errno_.
For reference, it's a classic C-like data-hiding/pseudoinheritance paradigm going on, the uv_fs_t contains a UV_FS_PRIVATE_FIELDS macro defining fields, and you can find the errno field here.
There is a lot of C++ template magic going on for translating the C++/v8 object to the uv_fs_t... it's good stuff, but very hard for me to parse without tons of coffee and several hours. I suspect one option, though would be to modify it to read from the libuv private fields that contain sys_errno_, then modify handleErrorFromBinding to also dump the underlying error code to stdout if req->result is UV_UNKNOWN. This would be ugly of course, inspecting private fields, but it would give much more useful information to the developer who's seeing things break in mysterious way. If I had the error code that libuv got I could file an issue there to add it to their error map - STATUS_FILE_CORRUPT_ERROR is a guess because procmon doesn't seem to translate it properly :) This is an ugly, platform-specific hack, but it would be better than nothing IMO.
I tried to be as thorough as possible in outlining the problematic path despite not having a drop-in repro, and I hope I provided enough info on my proposed fix.
There are a few related issues in node, and around github:
Update: The underlying error is actually 0x80070570/The file or directory is corrupted and unreadable, an HRESULT. I had to try and manually delete the folder to find this. It's just the HRESULT for 0x00000570/ERROR_FILE_CORRUPT. What a PITA. But, y'know, still would save me (and others) time if I had that error code at the beginning :)
Version
v16.14.2
Platform
Microsoft Windows NT 10.0.19044.0 x64
Subsystem
fs
What steps will reproduce the bug?
node
to invokelstat
on one of the corrupted files. For me specifically, this was a yarn operation.How often does it reproduce? Is there a required condition?
Intermittently (depends on file corruption), or constantly if the files remain corrupted. Because of Issue #34817, there is no useful stacktrace, so it's hard to say what operation specifically invokes the failing call.
What is the expected behavior?
Show the error code so a developer can debug the issue.
What do you see instead?
Error: UNKNOWN: unknown error, lstat 'C:\Users\Lucius Riccio\AppData\Local\Yarn\Data\global\node_modules\es-abstract\2022\GetV.js'
Additional information
As someone who's only mildly familiar with libuv, and barely familiar with node's C++ architecture, this was very hard to understand.
The first clue I had came while trying to figure out what the error was. I had to trace it in procmon to do that. The offending event was an
IRP_MJ_CREATE
(generated byNtCreateFile
up the stack) that failed with a result that procmon calledFILE CORRUPT
. I believe this refers to a0xC0000102
/STATUS_FILE_CORRUPT_ERROR
NTSTATUS code. It would be useful to show this, but I'll come back to that later.As best as I can tell, the node entry point/bridge from js to native for lstat is
LStat
, here.As best as I can tell, the
Error: UNKNOWN: unknown error, lstat
comes fromUVException
/hideStackFrames
, which uses theuv_fs_t* req
result field to translate the error code.The reason I'm filing this bug is that it looks like libuv has a way to get the underlying error code out (through
SET_REQ_WIN32_ERROR
) even if it's not a known error code. I think thatuv_fs_lstat
returns the translated error, but also stuffs the system errno in the privateDWORD
req->sys_errno_
.For reference, it's a classic C-like data-hiding/pseudoinheritance paradigm going on, the
uv_fs_t
contains aUV_FS_PRIVATE_FIELDS
macro defining fields, and you can find the errno field here.There is a lot of C++ template magic going on for translating the C++/v8 object to the
uv_fs_t
... it's good stuff, but very hard for me to parse without tons of coffee and several hours. I suspect one option, though would be to modify it to read from the libuv private fields that containsys_errno_
, then modifyhandleErrorFromBinding
to also dump the underlying error code to stdout ifreq->result
isUV_UNKNOWN
. This would be ugly of course, inspecting private fields, but it would give much more useful information to the developer who's seeing things break in mysterious way. If I had the error code that libuv got I could file an issue there to add it to their error map -STATUS_FILE_CORRUPT_ERROR
is a guess because procmon doesn't seem to translate it properly :) This is an ugly, platform-specific hack, but it would be better than nothing IMO.I tried to be as thorough as possible in outlining the problematic path despite not having a drop-in repro, and I hope I provided enough info on my proposed fix.
There are a few related issues in node, and around github:
unknown: unknown
and you will see twenty instances of this in this comment.Now I will go and see if deleting the files OR a chkdsk works around the problem for me!
The text was updated successfully, but these errors were encountered: