dotnet/wpf · error · InvalidEnumArgumentException

InvalidEnumArgumentException("textFormattingMode"…

Error message

InvalidEnumArgumentException("textFormattingMode", (int)textFormattingMode, typeof(TextFormattingMode))

What it means

TextFormatter.Create validates textFormattingMode against the defined TextFormattingMode values (Ideal=0, Display=1); anything outside 0..1 throws InvalidEnumArgumentException("textFormattingMode", ...). The mode chooses GDI-compatible or ideal metrics for text layout.

Solutions

  1. Call Create only with TextFormattingMode.Ideal or TextFormattingMode.Display
  2. Validate ints before casting: Enum.IsDefined(typeof(TextFormattingMode), v), else default to Ideal
  3. Fix or clamp the config value feeding the mode; default to Display for GDI-compatible metrics in DPI-heavy apps
  4. Catch InvalidEnumArgumentException around Create and retry with TextFormatter.Create(TextFormattingMode.Ideal)

Example fix

// before
var formatter = TextFormatter.Create((TextFormattingMode)modeInt); // modeInt = 5
// after
if (!Enum.IsDefined(typeof(TextFormattingMode), modeInt)) modeInt = (int)TextFormattingMode.Display;
var formatter = TextFormatter.Create((TextFormattingMode)modeInt);
Defensive patterns

Strategy: validation

Validate before calling

if (!Enum.IsDefined(typeof(TextFormattingMode), modeInt)) modeInt = (int)TextFormattingMode.Ideal;

Type guard

bool IsValidTextFormattingMode(int v) => v == (int)TextFormattingMode.Ideal || v == (int)TextFormattingMode.Display;

Try / catch

try { formatter = TextFormatter.Create(mode); }
catch (InvalidEnumArgumentException ex) { log.Warn("Invalid TextFormattingMode, using Display", ex); formatter = TextFormatter.Create(TextFormattingMode.Display); }

Prevention

When it happens

Trigger: Calling TextFormatter.Create with an invalid cast value, e.g. TextFormatter.Create((TextFormattingMode)5), or a mode read from config/serialization that is not 0 or 1.

Common situations: Persisting the formatting mode as an int in settings and restoring an out-of-range value; arithmetic or flags misuse on the enum; older code paths using removed enum members.

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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/textformatting/TextFormatter.cs:45

    /// for international text layout.
    /// 
    /// Unlike traditional text APIs, the TextFormatter interacts with a text layout client 
    /// through a set of callback methods. It requires the client to provide these methods 
    /// in an implementation of the TextSource class.
    /// </summary>
    public abstract class TextFormatter : IDisposable
    {
        private static readonly object _staticLock = new object();

        /// <summary>
        /// Client to create a new instance of TextFormatter
        /// </summary>
        /// <returns>New instance of TextFormatter</returns>
        public static TextFormatter Create(TextFormattingMode textFormattingMode)
        {
            if ((int)textFormattingMode < 0 || (int)textFormattingMode > 1)
            {
                throw new System.ComponentModel.InvalidEnumArgumentException("textFormattingMode", (int)textFormattingMode, typeof(TextFormattingMode));
            }
            
            // create a new instance of TextFormatter which allows the use of multiple contexts.
            return new TextFormatterImp(textFormattingMode);
        }

        /// <summary>
        /// Client to create a new instance of TextFormatter
        /// </summary>
        /// <returns>New instance of TextFormatter</returns>
        public static TextFormatter Create()
        {
            // create a new instance of TextFormatter which allows the use of multiple contexts.
            return new TextFormatterImp();
        }


        /// <summary>

View on GitHub (pinned to 81131a70a4)