Skip to content

Check srcpath with lstat in ensureSymlinkSync, like ensureSymlink - #1088

Open
abhu85 wants to merge 1 commit into
jprichardson:masterfrom
abhu85:fix-symlink-paths-sync-lstat
Open

abhu85 wants to merge 1 commit into
jprichardson:masterfrom
abhu85:fix-symlink-paths-sync-lstat

Conversation

@abhu85

@abhu85 abhu85 commented Sep 30, 2026

Copy link
Copy Markdown
Contributor

symlinkPathsSync checks srcpath with fs.existsSync, while the async symlinkPaths uses fs.lstat. existsSync follows symlinks, so the two disagree when srcpath is itself a broken symlink:

fs.symlinkSync('/tmp/missing-target', '/tmp/broken-src')

await fse.ensureSymlink('/tmp/broken-src', '/tmp/link-a')  // OK
fse.ensureSymlinkSync('/tmp/broken-src', '/tmp/link-b')    // Error: absolute srcpath does not exist

They also differ on a missing srcpath: ensureSymlink rejects with an ENOENT error (ENOENT: no such file or directory, ensureSymlink '...'), while ensureSymlinkSync throws a plain Error('absolute srcpath does not exist') (or 'relative ...') with no code.

This PR uses lstatSync in both branches of symlinkPathsSync, with the same error rewrite as the async version, so the sync API behaves like the async one.

User-visible changes to the sync API:

  • a srcpath that is itself a broken symlink is accepted, as in ensureSymlink;
  • a missing srcpath throws an ENOENT error with a code, instead of the plain "absolute/relative srcpath does not exist" message.

Nothing in the repo depends on the old messages. symlinkPathsSync is not exported.

Tests: added cases to lib/ensure/__tests__/symlink.test.js for a broken-symlink srcpath, both absolute and relative-to-cwd, and for the ENOENT code on a missing srcpath. All three fail without the change. npm test (standard, node test.js, node test.mjs): 748 passing.

symlinkPathsSync checked srcpath with fs.existsSync, which follows
symlinks, while the async symlinkPaths uses fs.lstat. So
ensureSymlinkSync rejected a srcpath that is itself a broken symlink,
which ensureSymlink accepts, and it threw a plain
"absolute srcpath does not exist" error without a code where
ensureSymlink rejects with ENOENT.

Use lstatSync with the same error handling as the async version.
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.

1 participant