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
- Call Create only with TextFormattingMode.Ideal or TextFormattingMode.Display
- Validate ints before casting: Enum.IsDefined(typeof(TextFormattingMode), v), else default to Ideal
- Fix or clamp the config value feeding the mode; default to Display for GDI-compatible metrics in DPI-heavy apps
- 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
- Only pass TextFormattingMode.Ideal or .Display to Create
- Validate settings/config integers with Enum.IsDefined before casting
- Default to Display for pixel-aligned UI text; Ideal for measurement-heavy scenarios
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
- CultureSource
- InvalidEnumArgumentException("Substitution", (int)value…
- SR.Format(SR.Enum_Invalid, typeof(TextMarkerStyle))
- Animation_UnrecognizedHandoffBehavior
- args
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)