Repository navigation
fs.readFile of directory on IBM i returns "Unknown system error -64" instead of "EISDIR" #25433
Description
Activity
@nodejs/platform-aix
@gireeshpunathil just a check, you are in the above group?
Reacted by Gireesh PunathilIf the only cause of
EOPNOTSUPPis that the fd refers to a directory, mapping it toEISDIRis obvious, but what if the fd is something else other than a directory that does not supportread()? In this case,EISDIRwould be wrong.Perhaps if read() returns
EOPNOTSUPP, it can fallback to thefstat()and return EISDIR if it was a dir, and just pass back ENOTSUPP otherwise? This would move the usually unnecessary fstat from the normal code path, to the failure path.@sam-github There are various ways to get
EOPNOTSUPP, not just for a attempting to read a directory so a simple mapping is not sufficient. The fallback to thefstat()as you proposed was what I was thinking as well, I just don't know if it's more appropriate to put that in Node or libuv.It should be in libuv. I suggest opening a PR there.
- addedfsIssues and PRs related to file-system APIs and the fs module.Issues and PRs related to file-system APIs and the fs module.aixIssues and PRs related to the AIX platform.Issues and PRs related to the AIX platform.
on Jan 13, 2019 @kadler Are you working on this? If not, I could revert libuv/libuv#2025 but with
s/_AIX/__PASE__/.- addedlibuvIssues and PRs related to the libuv dependency or the uv binding.Issues and PRs related to the libuv dependency or the uv binding.
on Jan 15, 2019 Yes, working on it, though I've been tied up with other things at the moment.
I've opened a libuv PR here: libuv/libuv#2148
- added a commit that references this issue
on Jan 17, 2019 This was fixed in libuv 1.25.0.
- added a commit that references this issue
on Apr 5, 2019 - added a commit that references this issue
on Jul 23, 2025 - added a commit that references this issue
on Dec 16, 2025
Since upgrade of libuv to 1.23.2 in #23336, fs.readFile on a directory on the IBM i platform returns "Unknown system error -64" instead of
EISDIR. (64 isEOPNOTSUPPon IBM i/PASE). Reproducing the problem is really easy:node -e "try { require('fs').readFileSync('.') } catch(err) { console.log(err.code) }"On Linux and macOS, this returns
EISDIR, while on IBM i this now returns "Unknown system error -64".This was changed in libuv/libuv#2025 to allow AIX to read a directory, since it's supported there (as in many BSDs and other OSes) and remove the performance penalty of doing a stat call for each read. Since the PASE environment where Node.js runs on IBM i is an AIX-like environment, this affected our platform as well, but unlike AIX, PASE does not support reading from directories.
The net result of this, is that global npm install are broken, due to gentle-fs assuming that reading from a directory will return
EISDIRorENOTASHIM: https://github.com/npm/gentle-fs/blob/latest/lib/rm.js#L245-L248So the question is what should happen here? I think at a minimum, err.code should be "EOPNOTSUPP" instead of "Unknown system error -64", but that still wouldn't actually fix the gentle-fs issue. libuv was deliberately changed due to the performance of the stat on each read, while gentle-fs has already done a stat and didn't bother to check if it was a directory first. gentle-fs could add a
stat.isDirectory()check prior to callingreadCmdShim, but I don't know enough about Windows to know if a cmd shim can be a directory. The other option is to standardize on theEISDIRbehavior and convert theEOPNOTSUPPon IBM i toEISDIR, but is then the question is whether that should happen in libuv or in Node.