nodejs / nodejs/node

fs: fs.link() on exFAT volumes (Windows) fails with misleading EISDIR instead of "not supported"

Đang mở
#65,817 6 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Ngôn ngữ chính
JavaScript
Star
122k
Fork
37.4k
Merge trung bình
4 ngày 3 giờ
Pull request đã merge (30 ngày)
272

Mô tả

  • Version: v24.19.0
  • Platform: Windows 11 Home (10.0.22631), x64 — NTFS system drive; two USB exFAT volumes (4TB / 2TB)
  • Subsystem: fs
What is wrong?

fs.linkSync(src, dest) targeting a file on an exFAT volume fails with errno EISDIR ("illegal operation on a directory"). The destination path does not exist and is not a directory. The real reason is that exFAT does not support hard links, and the underlying Win32 error is ERROR_INVALID_FUNCTION (WinError 1).

The EISDIR diagnosis actively misleads: it sends developers hunting for a directory that isn't there, instead of pointing at the unsupported filesystem operation.

Reproduction

On an exFAT-formatted volume (e.g. X:\):

$ node -e "require('fs').linkSync('X:\\a.tmp','X:\\b.tmp')"
Error: EISDIR: illegal operation on a directory, link 'X:\a.tmp' -> 'X:\b.tmp'

Python cross-check on the same volume shows the true underlying Win32 error:

$ python -c "import os; os.link(r'X:\a.tmp', r'X:\b.tmp')"
OSError: [WinError 1] 函数不正确。 (ERROR_INVALID_FUNCTION)

Observations from our test matrix (single machine, Windows 11 build 22631, Node v24.19.0):

Target volume Filesystem fs.linkSync result
C:, D:, F: NTFS succeeds
E: (USB), H: (USB) exFAT always fails with EISDIR

The failure splits perfectly along filesystem type, independent of internal/USB. Reads are unaffected; plain file writes work fine on exFAT.

Expected behavior

When CreateHardLinkW fails with ERROR_INVALID_FUNCTION on a filesystem without hard-link support, Node/libuv should surface a meaningful errno — e.g. ENOSYS ("function not implemented"), EPERM, or EOPNOTSUPP — rather than EISDIR.

For reference, on Linux, link(2) on filesystems that do not support hard links reports EPERM/EOPNOTSUPP, and on a system without the syscall at all ENOSYS.

Hypothesis (for upstream to confirm)

Possibly a missing mapping for ERROR_INVALID_FUNCTION in libuv's win32 uv_translate_sys_error, letting the failed uv_fs_link fall through to a misleading errno. We have not traced the exact layer; we only report the observed mapping WinError 1 (ERROR_INVALID_FUNCTION) → EISDIR.

Context / impact

This surfaced while diagnosing a third-party agent tool that publishes files via temp-file + hard-link: on exFAT drives every write failed, and the EISDIR message misattributed the cause. Reported downstream at https://github.com/deepseek-ai/deepseek-harness/discussions/5704 (includes the consumer-side analysis and a fallback-to-rename mitigation).

exFAT is the factory default format for many USB drives and SD cards, so "write to my external drive" is a common end-user scenario that hits this.

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Hướng nghiên cứu

Truy vết fs.link và uv_fs_link qua đường dẫn Windows CreateHardLinkW, sau đó kiểm tra ánh xạ uv_translate_sys_error của libuv cho ERROR_INVALID_FUNCTION. Xác nhận ánh xạ bằng cách tái hiện trên exFAT và thêm một regression test bao phủ errno nhận được; hoàn tất khi lỗi không còn báo cáo EISDIR và xác định thao tác không được hỗ trợ.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
javascript, node.js
Lĩnh vực
operating-systems
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Sôi nổi
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
55/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.