dotnet/wpf · error · ArgumentException

ThemeMode value is invalid. Use None, System, Light or Dark

Error message

ThemeMode value {0} is invalid. Use None, System, Light or Dark

What it means

The Application.ThemeMode setter only accepts None, System, Light, or Dark. ThemeManager.IsValidThemeMode validates the value; anything else throws ArgumentException with a message naming the invalid value and the allowed options. This guards the theme manager from undefined theme states.

Solutions

  1. Validate with Enum.IsDefined(typeof(ThemeMode), value) and map unknown values to ThemeMode.System
  2. Only assign the named members None, System, Light, Dark
  3. Coerce config/settings values through a TryParse-style mapper before assignment
  4. Set the property on the UI thread — the setter calls VerifyAccess

Example fix

// before
app.ThemeMode = (ThemeMode)settings.ThemeValue;
// after
var mode = Enum.IsDefined(typeof(ThemeMode), settings.ThemeValue) ? (ThemeMode)settings.ThemeValue : ThemeMode.System;
app.ThemeMode = mode;
Defensive patterns

Strategy: validation

Validate before calling

bool isValidTheme(int v) => Enum.IsDefined(typeof(ThemeMode), v) && (ThemeMode)v is ThemeMode.None or ThemeMode.System or ThemeMode.Light or ThemeMode.Dark;

Type guard

ThemeMode NormalizeTheme(int raw) => Enum.IsDefined(typeof(ThemeMode), raw) ? (ThemeMode)raw : ThemeMode.System;

Try / catch

try { app.ThemeMode = mode; } catch (ArgumentException) { app.ThemeMode = ThemeMode.System; }

Prevention

When it happens

Trigger: Assigning app.ThemeMode = (ThemeMode)rawInt from config or user input where the integer is not one of the four defined members; binding a string-typed setting directly to the property; passing a custom/unmapped enum value.

Common situations: User preferences stored as integers in settings files; two-way bindings delivering invalid values; theme enums extended or renamed between runtime versions.

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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Application.cs:971

        ///     in the application resources manually. If you do, the Fluent theme dictionaries added in the application
        ///     resources will take precedence over the ones added by setting this property.
        ///     
        ///     This property is experimental and may be removed in future versions.
        /// </remarks>
        [Experimental("WPF0001")]
        [TypeConverter(typeof(ThemeModeConverter))]
        public ThemeMode ThemeMode
        {
            get
            {
                return _themeMode;
            }
            set
            {
                VerifyAccess();
                if (!ThemeManager.IsValidThemeMode(value))
                {
                    throw new ArgumentException(string.Format("ThemeMode value {0} is invalid. Use None, System, Light or Dark", value));
                }
                
                ThemeMode oldValue = _themeMode;
                _themeMode = value;

                if(!_resourcesInitialized)
                {

                    ThemeManager.OnApplicationThemeChanged(oldValue, value);

                    // If the resources are not initializd, fluent dictionary
                    // included in this operation will be reset.
                    // Hence, we need to reload the fluent dictionary.
                    _reloadFluentDictionary = true;

                    // OnApplicationThemeChanged will trigger InvalidateResourceReferences
                    // which will mark _resourcesInitialized = true, however since 
                    // the value earlier was false, it means that Resources may not have been

View on GitHub (pinned to 81131a70a4)