fs: do not call Dir read callback twice - #65065
Open
shani-singh1 wants to merge 1 commit into
Open
Conversation
`Dir.prototype.read(callback)` invoked `callback` from inside a `try` block whose `catch` also calls `callback`. An exception thrown by user code inside the callback was therefore caught and passed back into the same callback as if the directory read itself had failed: the callback ran twice, the second time with the user's own error, and the original exception never reached `'uncaughtException'`. Compute the entry inside the `try` and invoke the callback after it, so only failures of the read itself are reported through the callback. Both the buffered and the asynchronous read paths are affected. Signed-off-by: Shani Singh <teamdeveloperworld@gmail.com>
shani-singh1
force-pushed
the
fs-dir-read-double-callback
branch
from
August 6, 2026 11:17
834ddfe to
c8a526c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Dir.prototype.read(callback)invokedcallbackfrom inside atryblock whosecatchalso callscallback:So an exception thrown by user code inside the callback is caught by the adjacent
catchand handed straight back to the same callback, as if the directory read itself had failed. Two things go wrong: the callback runs twice, and a plain bug in user code is silently reported to the application as an I/O error with a nonsense message while the original stack is lost.Reproduction
On v24.11.1:
Every other
fscallback lets the exception reach'uncaughtException'instead. For comparison,fs.readdir(tmp, () => { throw new Error('boom'); })reportsuncaughtException : boom.doc/api/fs.mddescribes one call per read, made after the read completes:The second call happens after completion, carrying an error that did not come from the read. Node also documents double invocation as an error condition in its own right (
ERR_MULTIPLE_CALLBACK, "A callback was called more than once").Change
Compute the entry inside the
tryand invoke the callback after it, so only failures of the read itself are reported through the callback. Both the buffered path and the asynchronousFSReqCallbackpath had the same shape and both are fixed.Verification
Running the real
lib/internal/fs/dir.js(before and after) against this build'sfs_dirbinding:The normal read paths are unchanged; only the throwing-callback case differs.