{"record":{"id":"3538a7a68fe90d15","repo":"LykosAI/StabilityMatrix","slug":"failed-to-delete-junction-point-targetdirectory","errorCode":null,"errorMessage":"Failed to delete junction point {targetDirectory}","messagePattern":"Failed to delete junction point (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"StabilityMatrix/ViewModels/PackageManagerViewModel.cs","lineNumber":246,"sourceCode":"    private void DeleteDirectory(string targetDirectory)\n    {\n        // Skip if directory does not exist\n        if (!Directory.Exists(targetDirectory))\n        {\n            return;\n        }\n        // For junction points, delete with recursive false\n        if (new DirectoryInfo(targetDirectory).LinkTarget != null)\n        {\n            logger.LogInformation(\"Removing junction point {TargetDirectory}\", targetDirectory);\n            try\n            {\n                Directory.Delete(targetDirectory, false);\n                return;\n            }\n            catch (IOException ex)\n            {\n                throw new IOException($\"Failed to delete junction point {targetDirectory}\", ex);\n            }\n        }\n        // Recursively delete all subdirectories\n        var subdirectoryEntries = Directory.GetDirectories(targetDirectory);\n        foreach (var subdirectoryPath in subdirectoryEntries)\n        {\n            DeleteDirectory(subdirectoryPath);\n        }\n        // Delete all files in the directory\n        var fileEntries = Directory.GetFiles(targetDirectory);\n        foreach (var filePath in fileEntries)\n        {\n            try\n            {\n                File.SetAttributes(filePath, FileAttributes.Normal);\n                File.Delete(filePath);\n            }\n            catch (IOException ex)","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/LykosAI/StabilityMatrix/blob/af93d6ef57c01cd890d7e0ad0a9ea8c9fcda3002/StabilityMatrix/ViewModels/PackageManagerViewModel.cs#L228-L264","documentation":"PackageManagerViewModel.DeleteDirectory removes junction points with Directory.Delete(path, false) (non-recursive, junction-only). If Windows throws an IOException — e.g. the junction is in use, broken, or access-denied — it is rethrown wrapped as 'Failed to delete junction point {targetDirectory}'.","triggerScenarios":"Deleting a package whose directory contains a junction/symlink, when Directory.Delete on the junction itself fails: a process holds a handle inside the target, the junction target is unavailable, or access is denied.","commonSituations":"A game/terminal/Explorer window has its working directory inside the junction; OneDrive/antivirus locking files under the link; the symlink target was removed leaving a broken junction that some filesystem states refuse to delete; deleting packages on a network drive.","solutions":["Close any programs (terminals, Explorer windows, editors) that are inside the package directory or its junction, then retry the delete.","Run the app elevated if the junction sits in a protected location and access was denied.","Delete the junction manually (rmdir on the junction path, which removes only the link) and retry the package delete.","Reboot or use SysInternals 'handle' to find and release the process holding a handle, then retry."],"exampleFix":"// manual fallback when app delete fails\ncmd /c rmdir \"C:\\path\\to\\junction\"   # removes the link, not the target\n// then retry the package deletion in Stability Matrix","handlingStrategy":"try-catch","validationCode":"if ((new DirectoryInfo(path).Attributes & FileAttributes.ReparsePoint) != 0 &&\n    IsDirectoryInUse(path)) return; // defer delete until handles are released","typeGuard":"static bool IsJunction(string path) =>\n    Directory.Exists(path) &&\n    (new DirectoryInfo(path).Attributes & FileAttributes.ReparsePoint) != 0;","tryCatchPattern":"try { await vm.DeleteDirectoryAsync(path); }\ncatch (IOException ex) when (ex.Message.StartsWith(\"Failed to delete junction point\"))\n{\n    logger.Warning(ex, \"Junction delete failed; retrying after handle release\");\n    // close locking processes or rmdir the junction, then retry\n}","preventionTips":["Don't keep terminals/Explorer open inside package directories or their junctions.","Release or stop processes (games, servers) before deleting packages.","Exclude package folders from antivirus/OneDrive sync locking where possible.","Delete junctions with 'rmdir <link>' semantics — never recursive deletes across the link."],"tags":["filesystem","junction","windows","delete"],"backgroundTag":"file-delete-failed","analyzedSha":"af93d6ef57c01cd890d7e0ad0a9ea8c9fcda3002","analyzedAt":"2026-09-12T19:02:43.389Z","contentChangedAt":"2026-09-12T19:02:43.389Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}