Skip to content

fs: opendirSync() leaks directory handle on error #58854

Description

@LiviaMedeiros

Version

v25.0.0-pre

Platform

Linux tumba 6.15.3-gentoo-yuran #1 SMP Sat Jun 21 21:02:19 +08 2025 x86_64 Intel(R) Core(TM)2 Quad CPU Q8200 @ 2.33GHz GenuineIntel GNU/Linux

Subsystem

fs

What steps will reproduce the bug?

test.mjs script:

importfsfrom'node:fs';{letdir;try{dir=fs.opendirSync(import.meta.dirname,{bufferSize: Infinity});console.log('successfully got',dir);}catch(e){console.log('dir is:',dir,'error is:',e);}finally{dir?.closeSync();}}globalThis.gc();setImmediate(()=>{});

Run it with expose GC flag:

$ node --expose-gc test.mjs

How often does it reproduce? Is there a required condition?

Always, assuming GC runs.

What is the expected behavior? Why is that the expected behavior?

The "successfully got" should not be printed.
The catched error must be ERR_OUT_OF_RANGE because of bad bufferSize.
The dir should be either:

  • An instance of fs.Dir that we can closeSync() gracefully
  • undefined assuming opendirSync internally did cleanup

And most importantly, this code must not emit any warnings.

What do you see instead?

dir is: undefinederroris: RangeError[ERR_OUT_OF_RANGE]: Thevalueof"options.bufferSize"isoutofrange.Itmustbeaninteger.ReceivedInfinityatnewDir(node:internal/fs/dir:61:5)atObject.opendirSync(node:internal/fs/dir:351:10)
at file:///tmp/test.mjs:5:14atModuleJob.run(node:internal/modules/esm/module_job:372:25)atasynconImport.tracePromise.__proto__(node:internal/modules/esm/loader:665:26)atasyncasyncRunEntryPointWithESMLoader(node:internal/modules/run_main:99:5){code: 'ERR_OUT_OF_RANGE'}(node:8286) Warning: Closingdirectoryhandleongarbagecollection(Use`node --trace-warnings ...`toshowwherethewarningwascreated)

Which means: dir stays undefined so we can not do anything about it, but the internal directory handle remains open until GC hunts it down.

Additional information

I haven't checked if fsPromises.opendir nor fs.opendir have similar problem but most likely they do.

I think this can be fixed on JS side, the patch is WIP.

Metadata

Metadata

Assignees

No one assigned

    Labels

    fsIssues and PRs related to the fs subsystem / file system.

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions