dotnet/wpf · error · IOException

SR.StorageAlreadyExist

Error message

SR.StorageAlreadyExist

What it means

Thrown by StorageInfo.CreateStorage when a sub-storage with the requested name already exists in this storage and the creation would overwrite it. The compound-file API surfaces this as IOException(SR.StorageAlreadyExist) instead of silently replacing the existing subtree.

Solutions

  1. Check StorageExists(name) before creating and reuse the existing storage if present
  2. Delete the existing storage first via Delete(recursive: true) if replacement is intended
  3. Use a unique name (e.g. include a GUID) when storages must be distinct
  4. Make initialization idempotent by fetching-or-creating rather than always creating

Example fix

// before
root.CreateSubStorage("Fragments");
// after
var fragments = root.StorageExists("Fragments")
    ? root.GetSubStorageInfo("Fragments")
    : root.CreateSubStorage("Fragments");
Defensive patterns

Strategy: validation

Validate before calling

if (storage.StorageExists(name)) return storage.GetSubStorageInfo(name); // reuse

Type guard

StorageInfo GetOrCreate(StorageInfo s, string name) => s.StorageExists(name) ? s.GetSubStorageInfo(name) : s.CreateSubStorage(name);

Try / catch

try { storage.CreateSubStorage(name); }
catch (IOException ex) when (ex.Message.Contains("exist")) { /* reuse existing */ }

Prevention

When it happens

Trigger: Calling CreateStorage/CreateSubStorage with a name for which StorageExists(name) is already true; re-running an idempotent initialization routine that always creates the same named storages.

Common situations: Re-opening and re-initializing an XPS package that already contains '\u0006DataSpaces' or 'Fragments' storages; retry logic that recreates the same names without checking existence first.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/d11479f5fd3c670b. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/System/IO/Packaging/CompoundFile/StorageInfo.cs:674

                            SR.Format(SR.NamedAPIFailure, "IStorage.CreateStorage"), 
                            nativeCallErrorCode ));
                }
                else
                {
                    throw new IOException(
                        SR.UnableToCreateStorage,
                        new COMException( 
                            SR.Format(SR.NamedAPIFailure, "IStorage.CreateStorage"), 
                            nativeCallErrorCode ));
                }
            }
    
            // Invalidate enumerators
            InvalidateEnumerators();
        }
        else
        {
            throw new IOException(SR.StorageAlreadyExist);
        }
    
        // Return a reference
        return newSubStorage;
    }
    
    /// <summary>
    /// Deletes a storage, recursively if specified.
    /// </summary>
    /// <param name="recursive">Whether to recursive delete all existing content</param>
    /// <param name="name">Name of storage</param>
    internal bool Delete( bool recursive , string name)
    {
        bool storageDeleted = false;
        CheckDisposedStatus();
        if( null == parentStorage )
        {
            // We are the root storage, you can't "delete" the root storage!

View on GitHub (pinned to 81131a70a4)