{"record":{"id":"3cee58870c4e4aef","repo":"LykosAI/StabilityMatrix","slug":"failed-to-delete-junction-point-directory-fullpath","errorCode":null,"errorMessage":"Failed to delete junction point {directory.FullPath}","messagePattern":"Failed to delete junction point (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"StabilityMatrix.Core/Extensions/DirectoryPathExtensions.cs","lineNumber":72,"sourceCode":"        cancellationToken.ThrowIfCancellationRequested();\n\n        // Skip if directory does not exist\n        if (!directory.Exists)\n        {\n            return;\n        }\n        // For junction points, delete with recursive false\n        if (directory.IsSymbolicLink)\n        {\n            logger?.LogInformation(\"Removing junction point {TargetDirectory}\", directory.FullPath);\n            try\n            {\n                directory.Delete(false);\n                return;\n            }\n            catch (IOException ex)\n            {\n                throw new IOException($\"Failed to delete junction point {directory.FullPath}\", ex);\n            }\n        }\n        // Recursively delete all subdirectories\n        foreach (var subDir in directory.EnumerateDirectories())\n        {\n            DeleteVerbose(subDir, logger, cancellationToken);\n        }\n\n        // Delete all files in the directory\n        foreach (var filePath in directory.EnumerateFiles())\n        {\n            cancellationToken.ThrowIfCancellationRequested();\n\n            try\n            {\n                filePath.Info.Attributes = FileAttributes.Normal;\n                filePath.Delete();\n            }","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/LykosAI/StabilityMatrix/blob/af93d6ef57c01cd890d7e0ad0a9ea8c9fcda3002/StabilityMatrix.Core/Extensions/DirectoryPathExtensions.cs#L54-L90","documentation":"DeleteVerbose wraps directory delete failures in an IOException naming the junction point path. The directory.Delete(false) call failed with an IOException (non-fatal OS error like in-use, permissions, or reparse-point issues). It rethrows with the full path preserved as the message so the caller knows exactly which junction failed.","triggerScenarios":"DeleteVerbose/DeleteVerboseAsync encounters an IOException when calling directory.Delete(false) on a junction point directory, e.g. the junction target is locked, a handle is open, or the reparse point cannot be removed.","commonSituations":"Deleting an installed package directory that contains symlinks/junctions while the target (e.g. a running ComfyUI venv or a mounted model folder) is in use; antivirus or a shell holding the junction open; partial cleanup after a failed delete pass left the junction in a bad state.","solutions":["Close processes holding handles to the junction or its target (check with handle.exe/lsof), then retry the delete","Verify the process has write/delete permission on the junction and its parent directory","Check the inner exception for the exact OS error and whether the junction target still exists","As a fallback, remove the junction explicitly with fsutil reparsepoint delete (Windows) before deleting the directory"],"exampleFix":"// before\ndirectory.Delete(false);\n// after\n// release handles / remove reparse point first\nif (directory.LinkTarget is not null)\n{\n    Process.Start(\"fsutil\", $\"reparsepoint delete \\\"{directory.FullPath}\\\"\")?.WaitForExit();\n}\ndirectory.Delete(false);","handlingStrategy":"try-catch","validationCode":"if (Directory.Exists(path))\n{\n    var di = new DirectoryInfo(path);\n    if (di.Attributes.HasFlag(FileAttributes.ReparsePoint))\n        Console.WriteLine($\"Junction at {path} -> {di.LinkTarget}; ensure target is not in use\");\n}","typeGuard":"static bool IsJunction(DirectoryInfo d) =>\n    d.Attributes.HasFlag(FileAttributes.ReparsePoint) && d.LinkTarget is not null;","tryCatchPattern":"try { DirectoryPathExtensions.DeleteVerbose(dir, logger, ct); }\ncatch (IOException ex) when (ex.InnerException is not null)\n{\n    logger.LogWarning(ex, \"Delete failed for {Path}; retry after releasing handles\", dir);\n    // retry once after delay or surface to user\n}","preventionTips":["Close apps/handles using the directory before deleting","Exclude install dirs from antivirus and indexers","Remove reparse points explicitly before recursive delete","Run cleanup with sufficient privileges"],"tags":["io","filesystem","junction","windows"],"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"}