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

  1. Verify every path passed to the operation exists (File.Exists/Directory.Exists) immediately before the call.
  2. Re-check the path for invalid characters or device/UNC issues and normalize it to a full absolute path.
  3. Confirm the drive/volume hosting the path is mounted and accessible.
  4. 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

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


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)