Fix Directory.Delete(recursive: true) failing on directories containing junctions#124830
Draft
Fix Directory.Delete(recursive: true) failing on directories containing junctions#124830
Conversation
…tions - Use a local `mountPointException` variable in RemoveDirectoryRecursive when handling IO_REPARSE_TAG_MOUNT_POINT reparse points. Previously, if DeleteVolumeMountPoint() failed (as it always does for directory junctions, which share the same reparse tag as volume mount points), the error was stored in `exception`, causing the parent directory deletion to fail even though RemoveDirectory() would succeed. - Now mountPointException is only promoted to exception if RemoveDirectory also fails. If RemoveDirectory succeeds (the normal case for junctions), the DeleteVolumeMountPoint error is discarded. - Add test RecursiveDelete_DirectoryContainingJunction to verify the fix. Co-authored-by: ViveliDuCh <50237907+ViveliDuCh@users.noreply.github.com>
Co-authored-by: ViveliDuCh <50237907+ViveliDuCh@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Fix Directory.Delete failure on directories containing junctions
Fix Directory.Delete(path, recursive: true) failing on directories containing junctions
Feb 24, 2026
This was referenced Feb 25, 2026
Open
Co-authored-by: ViveliDuCh <50237907+ViveliDuCh@users.noreply.github.com>
Copilot
AI
changed the title
Fix Directory.Delete(path, recursive: true) failing on directories containing junctions
Fix Directory.Delete(recursive: true) failing on directories containing junctions
Feb 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Directory.Delete(path, recursive: true)throws when the target directory contains NTFS junctions. The junction is removed but the parent directory is left behind.Description
Root cause:
IO_REPARSE_TAG_MOUNT_POINTis shared by both volume mount points and directory junctions.RemoveDirectoryRecursivecalledDeleteVolumeMountPointon all entries with this tag, but that API only works for volume mount points — it always fails for junctions. That failure was stored directly inexception, blockingRemoveDirectoryInternalfrom running on the parent even though the subsequentRemoveDirectorycall succeeded and removed the junction.Fix: Capture the
DeleteVolumeMountPointfailure in a localmountPointExceptioninstead of the loop'sexception. Only promote it toexceptionifRemoveDirectoryalso fails. For junctions,RemoveDirectorysucceeds and the local exception is discarded.Test: Added
RecursiveDelete_DirectoryContainingJunction(Windows-only) — creates a parent directory with a junction to a separate target, callsDirectory.Delete(parent, true), and asserts the parent is gone while the junction target is untouched.Original prompt
This section details on the original issue you should resolve
<issue_title>Directory.Delete(path, recursive: true) fails on directories containing junctions</issue_title>
<issue_description>### Description
On Windows, when recursively deleting a directory containing a junction,
System.IO.Directory.Delete(String, Boolean)fails.Symbolic links work as expected.
Reproduction Steps
Since there's no API to create junctions, this is mostly easily reproduced in powershell:
Expected behavior
The parent directory and junction should be removed successfully.
Actual behavior
The junction is removed, but the parent directory is left behind. The exception message depends on whether the script is run as administrator or not:
Non-admin
Admin
Regression?
I'm able to reproduce this using the script in both powershell 5.1.19041.2673 (.NET Framework 4.8.4614.0), and powershell core 7.2.11 (.NET 6.0.16)
Known Workarounds
Since the junction is removed, the operation can simply be retried to workaround the issue.
Configuration
Reproduced on Windows 22H2 (build 19045.2846)
Other information
No response</issue_description>
<agent_instructions>Look at the existing discussion about it and the suggested/explored fix for this following similar dotnet/runtime existing pattern for the test coverage requested. At the end, give an md file detailing on the reasoning behind each decision taken and the technical explanation of the solution and the background (the request that satisfies and how it does it).</agent_instructions>
Comments on the Issue (you are @copilot in this section)
@ Tagging subscribers to this area: @dotnet/area-system-io See info in [area-owners.md](https://github.com/dotnet/runtime/blob/main/docs/area-owners.md) if you want to be subscribed.Issue Details
Description
On Windows, when recursively deleting a directory containing a junction,
System.IO.Directory.Delete(String, Boolean)fails.Reproduction Steps
Since there's no API to create hardlinks (#69030), this is mostly easily reproduced in powershell: