dotnet/wpf · error · ArgumentException

SR.CreateModeMustBeCreateOrOpen

Error message

SR.CreateModeMustBeCreateOrOpen

What it means

StorageRoot.CreateOnStream only supports FileMode.Create and FileMode.Open; any other FileMode (CreateNew, OpenOrCreate, Truncate, Append) reaches the else branch and throws ArgumentException with SR.CreateModeMustBeCreateOrOpen. The COM StgCreateDocfile/StgOpenStorage mapping is only defined for these two modes.

Solutions

  1. Pass FileMode.Open to open an existing container or FileMode.Create to create/overwrite one.
  2. Map other modes before the call: OpenOrCreate -> check existence then Open or Create; CreateNew -> check existence, then Create; Truncate -> Create on a truncated stream.
  3. Reject unsupported modes early in your own API with a clear message.
  4. See docs: StorageRoot on-stream creation accepts only Create and Open.

Example fix

// before
var root = StorageRoot.CreateOnStream(stream, FileMode.OpenOrCreate, FileAccess.ReadWrite); // ArgumentException
// after
var mode = stream.CanRead && stream.Length > 0 ? FileMode.Open : FileMode.Create;
var root = StorageRoot.CreateOnStream(stream, mode, FileAccess.ReadWrite);
Defensive patterns

Strategy: validation

Validate before calling

private static readonly HashSet<FileMode> Allowed = new() { FileMode.Create, FileMode.Open };
if (!Allowed.Contains(mode))
    throw new ArgumentException("Only FileMode.Create and FileMode.Open are supported", nameof(mode));

Prevention

When it happens

Trigger: Calling StorageRoot.CreateOnStream with FileMode.CreateNew, OpenOrCreate, Truncate, or Append — e.g. passing FileMode.OpenOrCreate because that is habitual for FileStream usage.

Common situations: Refactoring code that used FileStream constructors with OpenOrCreate; generic stream-opening helpers that forward arbitrary FileMode values into the compound-file layer.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/System/IO/Packaging/CompoundFile/StorageRoot.cs:149

        }

        if( FileMode.Create == mode )
        {
            returnValue = SafeNativeCompoundFileMethods.SafeStgCreateDocfileOnStream(
                baseStream,
                openFlags | SafeNativeCompoundFileConstants.STGM_CREATE,
                out storageOnStream);
        }
        else if( FileMode.Open == mode )
        {
            returnValue = SafeNativeCompoundFileMethods.SafeStgOpenStorageOnStream(
                baseStream,
                openFlags,
                out storageOnStream );
        }
        else
        {
            throw new ArgumentException(
                SR.CreateModeMustBeCreateOrOpen);
        }
        
        switch( (uint) returnValue )
        {
            case SafeNativeCompoundFileConstants.S_OK:
                return StorageRoot.CreateOnIStorage( 
                    storageOnStream );

            default:
                throw new IOException(
                    SR.UnableToCreateOnStream,
                    new COMException(
                        SR.CFAPIFailure, 
                        returnValue));
        }
    }

View on GitHub (pinned to 81131a70a4)