dotnet/wpf · error · InvalidEnumArgumentException

origin

Error message

origin

What it means

CFStream.Seek throws InvalidEnumArgumentException when the origin parameter is not one of the three SeekOrigin values (Begin, Current, End). The default case of the switch rejects any out-of-range or undefined enum value before it can be forwarded to the native compound-file IStream. This protects the native call from an unmapped seek-origin constant.

Solutions

  1. Only pass SeekOrigin.Begin, SeekOrigin.Current, or SeekOrigin.End
  2. Validate the raw value before casting: if (Enum.IsDefined(typeof(SeekOrigin), value))
  3. Catch InvalidEnumArgumentException to detect corrupted origin data

Example fix

// before
stream.Seek(offset, (SeekOrigin)rawValue);
// after
if (!Enum.IsDefined(typeof(SeekOrigin), rawValue)) throw new ArgumentException(nameof(rawValue));
stream.Seek(offset, (SeekOrigin)rawValue);
Defensive patterns

Strategy: validation

Validate before calling

if (!Enum.IsDefined(typeof(SeekOrigin), origin)) throw new InvalidEnumArgumentException(nameof(origin), (int)origin, typeof(SeekOrigin));

Type guard

static bool IsDefinedSeekOrigin(SeekOrigin o) => o is SeekOrigin.Begin or SeekOrigin.Current or SeekOrigin.End;

Try / catch

try { stream.Seek(offset, origin); } catch (System.ComponentModel.InvalidEnumArgumentException ex) { /* reject bad origin */ }

Prevention

When it happens

Trigger: Calling Seek with an invalid cast, e.g. stream.Seek(0, (SeekOrigin)7) or an uninitialized/garbage SeekOrigin variable.

Common situations: Reading the origin from config/data or interop code that stores it as int; enum values from older or mismatched API versions; unvalidated deserialized enum fields.

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/87924cfff8b4d793. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/CFStream.cs:174

                translatedSeekOrigin = SafeNativeCompoundFileConstants.STREAM_SEEK_SET;
                if( 0 > offset )
                {
                    throw new ArgumentOutOfRangeException(nameof(offset),
                        SR.SeekNegative);
                }
                break;
            case SeekOrigin.Current:
                translatedSeekOrigin = SafeNativeCompoundFileConstants.STREAM_SEEK_CUR;
                // Need to find the current seek pointer to see if we'll end
                //  up with a negative position.
                break;
            case SeekOrigin.End:
                translatedSeekOrigin = SafeNativeCompoundFileConstants.STREAM_SEEK_END;
                // Need to find the current seek pointer to see if we'll end
                //  up with a negative position.
                break;
            default:
                throw new System.ComponentModel.InvalidEnumArgumentException("origin", (int) origin, typeof(SeekOrigin));
        }

        _safeIStream.Seek( offset, translatedSeekOrigin, out seekPos );

        return seekPos;
    }

    /// <summary>
    /// See .NET Framework SDK under System.IO.Stream
    /// </summary>
    /// <param name="newLength">New length</param>
    public override void SetLength( long newLength )
    {
        CheckDisposedStatus();

        if (!CanWrite)
        {
            throw new NotSupportedException(SR.SetLengthNotSupported);

View on GitHub (pinned to 81131a70a4)