LykosAI/StabilityMatrix · error · Win32Exception
Win32Exception (native Win32 error from…
Error message
Win32Exception (native Win32 error from Marshal.GetLastWin32Error) during shell item creation
What it means
CreateShellItemArray converts filesystem paths to PIDLs via SHParseDisplayName before building an IShellItemArray for Explorer shell operations. If SHParseDisplayName returns a non-zero HRESULT for any path, a Win32Exception built from Marshal.GetLastWin32Error is thrown, indicating Windows could not resolve the path into a shell item.
Solutions
- Verify every path passed to the operation exists (File.Exists/Directory.Exists) immediately before the call.
- Re-check the path for invalid characters or device/UNC issues and normalize it to a full absolute path.
- Confirm the drive/volume hosting the path is mounted and accessible.
- Retry the operation; if it persists, run elevated or fall back to a plain (non-shell) delete.
Example fix
// before
await fileOps.DeleteItems(new[] { path });
// after
if (File.Exists(path) || Directory.Exists(path))
await fileOps.DeleteItems(new[] { Path.GetFullPath(path) }); Defensive patterns
Strategy: try-catch
Validate before calling
var missing = paths.Where(p => !File.Exists(p) && !Directory.Exists(p)).ToList();
if (missing.Count > 0) throw new FileNotFoundException("Paths missing before shell op", string.Join(",", missing)); Type guard
static bool IsShellPathUsable(string path) =>
!string.IsNullOrWhiteSpace(path) && (File.Exists(path) || Directory.Exists(path)) && path.IndexOfAny(Path.GetInvalidPathChars()) < 0; Try / catch
try { await fileOps.DeleteItems(paths); }
catch (Win32Exception ex)
{
logger.Warning(ex, "Shell item creation failed (win32 err {Code})", ex.NativeErrorCode);
// fallback: plain File/Directory delete or retry after re-verifying paths
} Prevention
- Re-verify existence of all paths immediately before shell operations.
- Normalize paths to full absolute paths and strip invalid characters.
- Handle network/USB volumes being unavailable before operating on them.
- Provide a non-shell fallback delete when shell operations fail.
When it happens
Trigger: Calling shell file operations (delete/recycle via the Windows FileOperationWrapper) with a path that fails SHParseDisplayName: nonexistent file, invalid characters, a path on an unavailable drive, or insufficient access.
Common situations: Recycling a file that was already deleted by another process; paths with illegal characters or exceeding MAX_PATH on old Windows; network/USB drive disconnected mid-operation; antivirus locking the item.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Failed 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.
- Unable to delete junction point.
AI-assisted analysis of LykosAI/StabilityMatrix@af93d6ef57 (2026-09-12).
Data as JSON: /api/errors/6ab170de8eae94fe.
Report an issue: GitHub.
Appendix: source
Thrown at StabilityMatrix.Native.Windows/FileOperations/FileOperationWrapper.cs:173
// Normalize path slashes
path = path.Replace('/', '\\');
return new ComReleaser<IShellItem>(
(IShellItem)SHCreateItemFromParsingName(path, IntPtr.Zero, ref _shellItemGuid)
);
}
private static ComReleaser<IShellItemArray> CreateShellItemArray(params string[] paths)
{
var pidls = new IntPtr[paths.Length];
try
{
for (var i = 0; i < paths.Length; i++)
{
if (SHParseDisplayName(paths[i], IntPtr.Zero, out var pidl, 0, out _) != 0)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
pidls[i] = pidl;
}
return new ComReleaser<IShellItemArray>(
SHCreateShellItemArrayFromIDLists((uint)pidls.Length, pidls)
);
}
finally
{
foreach (var pidl in pidls)
{
Marshal.FreeCoTaskMem(pidl);
}
}
}
View on GitHub (pinned to af93d6ef57)