Skip to content

fs: pass symlink type in cp when filter is provided#62654

Open
shulaoda wants to merge 2 commits intonodejs:mainfrom
shulaoda:04-10-fs_pass_symlink_type_in_cp_when_filter_is_provided
Open

fs: pass symlink type in cp when filter is provided#62654
shulaoda wants to merge 2 commits intonodejs:mainfrom
shulaoda:04-10-fs_pass_symlink_type_in_cp_when_filter_is_provided

Conversation

@shulaoda
Copy link
Copy Markdown

@shulaoda shulaoda commented Apr 9, 2026

When fs.cp/fs.cpSync is called with both verbatimSymlinks: true and a filter function, directory symlinks are incorrectly created as file symlinks on Windows.

Root cause

fs.cp takes two code paths:

  • Without filter: the C++ fast path (cpSyncCopyDir) uses std::filesystem::copy_symlink() which preserves the symlink type automatically.
  • With filter: the JS fallback path calls symlinkSync(resolvedSrc, dest) without a type parameter. On Windows, symlinkSync tries to auto-detect the type by stat-ing the resolved target at the destination. During a recursive copy, the target directory may not yet exist at the destination (e.g. linked/ is copied before packages/ in alphabetical order), so stat fails and type defaults to 'file' creating a file symlink instead of a directory symlink.

Fix

Detect the symlink type from the source (which always exists) using internalModuleStat(src) and pass it explicitly to symlinkSync/symlink. The onLink function already computed srcIsDir for subdirectory validation but only after the early-return paths this change moves it before those returns and threads the derived symlinkType through to all symlinkSync/symlink call sites.

Both the sync (cp-sync.js) and async (cp.js) implementations are fixed.

Test

Added two test files that verify directory symlinks are preserved when copying with verbatimSymlinks: true and a filter function:

  • test-fs-cp-sync-verbatim-dir-symlinks-with-filter.mjs
  • test-fs-cp-async-verbatim-dir-symlinks-with-filter.mjs

Fixes: #62653

@shulaoda shulaoda marked this pull request as ready for review April 9, 2026 16:25
@nodejs-github-bot nodejs-github-bot added fs Issues and PRs related to the fs subsystem / file system. needs-ci PRs that need a full CI run. labels Apr 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fs Issues and PRs related to the fs subsystem / file system. needs-ci PRs that need a full CI run.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fs.cp creates file symlink instead of directory symlink on Windows when filter is provided

4 participants