Tcl Source Code

View Ticket
Login
Ticket UUID: 08203e40e341386c6dc5aac0b8405e506f658656
Title: Windows: [file delete -force] fails on a directory containing a symlink
Type: Bug Created on: 2026-10-17 10:51:12
Submitter: serhiy.storchaka Assigned to:
Subsystem: 37. File System Severity: Minor
Priority: 5 Medium Last modified: 2026-10-20 18:11:29
Status: Open Closed by:
Resolution: None Closed on:
Version: 8.6.18, 9.0.5, 9.1.0
Description:

On Windows, [file delete -force] fails on a directory that contains a file symbolic link. Tcl itself creates such links: [file link -symbolic] makes a real symlink for a file target since 8.6.11 ([548cd945d6]). This needs administrator rights or Developer Mode, the same as mklink.

file mkdir d
close [open d/a.txt w]
file link -symbolic d/b.txt d/a.txt   ;# or: mklink d\b.txt a.txt
file delete -force d

Actual: error deleting "...": invalid argument, and d stays. Expected: d is deleted. Deleting the link itself with [file delete d/b.txt] works.

Cause: TraverseWinTree() (win/tclWinFCmd.c) hands every reparse point to TraversalDelete() as DOTREE_LINK, which calls DoRemoveJustDirectory() and so TclWinSymLinkDelete() (win/tclWinFile.c). That function always passes IO_REPARSE_TAG_MOUNT_POINT to FSCTL_DELETE_REPARSE_POINT, which fails with a tag mismatch for a symlink (tag 0xA000000C), giving EINVAL. Even if the reparse data were removed, RemoveDirectoryW() cannot remove a file. A directory symlink inside the tree goes through the same code and probably fails the same way. The same function also explains [3c13c4ed31] ([file delete] on a directory symlink fails with "illegal operation on a directory"/"is a directory"), which was closed as Invalid. Possible fix: delete links with DeleteFileW() or RemoveDirectoryW() depending on FILE_ATTRIBUTE_DIRECTORY. Both remove the link and not its target.

Related: [972c35d41d] ([file copy] of symlinks), [c8d4f01a54] (NTFS symlinks not supported by [file]).

Seen on Windows 11 in 8.6.18, 9.0.5 and 9.1.

User Comments:
serhiy.storchaka added on 2026-10-17 14:27:36:

Proposed fix in branch win-delete-tree-with-symlinks: a link to a file is removed like a file, and a link to a directory that is not a junction (mklink /D) with RemoveDirectoryW(); the targets are not touched. Directory symbolic links inside the tree failed the same way. Tests winFCmd-9.7 and 9.8 (need the right to create symbolic links).