Skip to content

fix: do not throw when fs.close is getter-only - #262

Closed
dyk1454683243-sudo wants to merge 2 commits into
isaacs:mainfrom
dyk1454683243-sudo:cursor/fix-close-getter-only-5b33
Closed

dyk1454683243-sudo wants to merge 2 commits into
isaacs:mainfrom
dyk1454683243-sudo:cursor/fix-close-getter-only-5b33

Conversation

@dyk1454683243-sudo

@dyk1454683243-sudo dyk1454683243-sudo commented Sep 20, 2026

Copy link
Copy Markdown

Fixes #257

Problem

On some Node / bundler setups (Vite, esbuild, ESM interop), require('fs') is a namespace-style object whose methods are getter-only. graceful-fs then does:

fs.close = function close () { /* queue reset */ }

and throws:

TypeError: Cannot set property close of #<Object> which has only a getter
    at graceful-fs.js:52

This shows up through fs-extragraceful-fs when the dependency graph is pre-bundled.

Fix

  • Assign fs.close / fs.closeSync only when the property is writable or has a setter.
  • If it is getter-only but configurable, replace it with defineProperty.
  • If it is getter-only and non-configurable, skip the global patch instead of throwing.
  • Materialize getter-only properties on the cloned export so that lookalike can still be patched.
  • If the real fs.close could not be assigned, still wrap close on the exported object so EMFILE retries keep working for graceful-fs callers.

Normal Node is unchanged: fs.close remains a writable data property, so the existing assignment path is used.

Tests

test/close-getter-only.js:

  • configurable getter-only close is patched (defineProperty path)
  • patched close / closeSync still open and close real file descriptors
  • non-configurable getter-only close loads without throwing and leaves the real fs method alone
  • clone() turns getter-only properties into writable data properties

Local npm test: 49460 passing.

Does not overlap with #261 (large writeFile).

cursoragent and others added 2 commits September 20, 2026 18:52
Bundlers and ESM interop (Vite/esbuild) expose fs methods as
getter-only properties, so `fs.close = ...` throws TypeError.
Only assign when the property is writable or configurable, and
materialize getter-only properties on the cloned export so it
can still be patched.

Fixes isaacs#257

Co-authored-by: David <dyk1454683243-sudo@users.noreply.github.com>
Co-authored-by: David <dyk1454683243-sudo@users.noreply.github.com>
@isaacs isaacs closed this Sep 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cannot set property close of #<Object> which has only a getter

3 participants