Repository: nodejs/node
Pull request: fs: deprecate never throw behaviour in fs.existsSync

This PR attempts to deprecate the behaviour of returning false on argument validation in `fs.existsSync`

cc @joyeecheung @BridgeAR
<!--
Before submitting a pull request, please read:

- the CONTRIBUTING guide at https://github.com/nodejs/node/blob/HEAD/CONTRIBUTING.md
- the commit message formatting guidelines at
  https://github.com/nodejs/node/blob/HEAD/doc/contributing/pull-requests.md#commit-message-guidelines

For code changes:
1. Include tests for any bug fixes or new features.
2. Update documentation if relevant.
3. Ensure that `make -j4 test` (UNIX), or `vcbuild test` (Windows) passes.

If you believe this PR should be highlighted in the Node.js CHANGELOG
please add the `notable-change` label.

Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
    have the right to submit it under the open source license
    indicated in the file; or

(b) The contribution is based upon previous work that, to the best
    of my knowledge, is covered under an appropriate open source
    license and I have the right under that license to submit that
    work with modifications, whether created in whole or in part
    by me, under the same open source license (unless I am
    permitted to submit under a different license), as indicated
    in the file; or

(c) The contribution was provided directly to me by some other
    person who certified (a), (b) or (c) and I have not modified
    it.

(d) I understand and agree that this project and the contribution
    are public and that a record of the contribution (including all
    personal information I submit with it, including my sign-off) is
    maintained indefinitely and may be redistributed consistent with
    this project or the open source license(s) involved.
-->


Changed files:
filename: doc/api/deprecations.md
patch: @@ -3779,14 +3779,17 @@ It is recommended to use the `new` qualifier instead. This applies to all REPL c
 
 <!-- YAML
 changes:
+  - version: REPLACEME
+    pr-url: https://github.com/nodejs/node/pull/55753
+    description: Runtime deprecation.
   - version:
     - v23.4.0
     - v22.13.0
     pr-url: https://github.com/nodejs/node/pull/55892
     description: Documentation-only.
 -->
 
-Type: Documentation-only
+Type: Runtime
 
 Passing non-supported argument types is deprecated and, instead of returning `false`,
 will throw an error in a future version.

filename: lib/fs.js
patch: @@ -273,12 +273,7 @@ ObjectDefineProperty(exists, kCustomPromisifiedSymbol, {
   },
 });
 
-// fs.existsSync never throws, it only returns true or false.
-// Since fs.existsSync never throws, users have established
-// the expectation that passing invalid arguments to it, even like
-// fs.existsSync(), would only get a false in return, so we cannot signal
-// validation errors to users properly out of compatibility concerns.
-// TODO(joyeecheung): deprecate the never-throw-on-invalid-arguments behavior
+let showExistsDeprecation = true;
 /**
  * Synchronously tests whether or not the given path exists.
  * @param {string | Buffer | URL} path
@@ -288,6 +283,12 @@ function existsSync(path) {
   try {
     path = getValidatedPath(path);
   } catch {
+    if (showExistsDeprecation) {
+      process.emitWarning(
+        'Passing invalid argument types to fs.existsSync is deprecated', 'DeprecationWarning', 'DEP0187',
+      );
+      showExistsDeprecation = false;
+    }
     return false;
   }
 

filename: test/parallel/test-fs-exists.js
patch: @@ -51,6 +51,8 @@ assert(fs.existsSync(f));
 assert(!fs.existsSync(`${f}-NO`));
 
 // fs.existsSync() never throws
+const msg = 'Passing invalid argument types to fs.existsSync is deprecated';
+common.expectWarning('DeprecationWarning', msg, 'DEP0187');
 assert(!fs.existsSync());
 assert(!fs.existsSync({}));
 assert(!fs.existsSync(new URL('https://foo')));