LykosAI/StabilityMatrix · error · IOException
Failed to delete junction point
Error message
Failed to delete junction point {directory.FullPath} What it means
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.
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
Example fix
// before
directory.Delete(false);
// after
// release handles / remove reparse point first
if (directory.LinkTarget is not null)
{
Process.Start("fsutil", $"reparsepoint delete \"{directory.FullPath}\"")?.WaitForExit();
}
directory.Delete(false); Defensive patterns
Strategy: try-catch
Validate before calling
if (Directory.Exists(path))
{
var di = new DirectoryInfo(path);
if (di.Attributes.HasFlag(FileAttributes.ReparsePoint))
Console.WriteLine($"Junction at {path} -> {di.LinkTarget}; ensure target is not in use");
} Type guard
static bool IsJunction(DirectoryInfo d) =>
d.Attributes.HasFlag(FileAttributes.ReparsePoint) && d.LinkTarget is not null; Try / catch
try { DirectoryPathExtensions.DeleteVerbose(dir, logger, ct); }
catch (IOException ex) when (ex.InnerException is not null)
{
logger.LogWarning(ex, "Delete failed for {Path}; retry after releasing handles", dir);
// retry once after delay or surface to user
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Unable to delete junction point.
- Target path does not exist or is not a directory
- Directory already exists and overwrite parameter is false.
- Path is not a junction point.
- Failed to delete junction point
AI-assisted analysis of LykosAI/StabilityMatrix@af93d6ef57 (2026-09-12).
Data as JSON: /api/errors/3cee58870c4e4aef.
Report an issue: GitHub.
Appendix: source
Thrown at StabilityMatrix.Core/Extensions/DirectoryPathExtensions.cs:72
cancellationToken.ThrowIfCancellationRequested();
// Skip if directory does not exist
if (!directory.Exists)
{
return;
}
// For junction points, delete with recursive false
if (directory.IsSymbolicLink)
{
logger?.LogInformation("Removing junction point {TargetDirectory}", directory.FullPath);
try
{
directory.Delete(false);
return;
}
catch (IOException ex)
{
throw new IOException($"Failed to delete junction point {directory.FullPath}", ex);
}
}
// Recursively delete all subdirectories
foreach (var subDir in directory.EnumerateDirectories())
{
DeleteVerbose(subDir, logger, cancellationToken);
}
// Delete all files in the directory
foreach (var filePath in directory.EnumerateFiles())
{
cancellationToken.ThrowIfCancellationRequested();
try
{
filePath.Info.Attributes = FileAttributes.Normal;
filePath.Delete();
}View on GitHub (pinned to af93d6ef57)