tui-cs/Terminal.Gui · error · InvalidOperationException

Theme cannot be set before ConfigurationManager is initializ

Error message

Theme cannot be set before ConfigurationManager is initialized.

What it means

Thrown by the ThemeManager.Theme setter when ConfigurationManager.IsInitialized() returns false. The Theme backing store lives in ConfigurationManager.Settings["Theme"], which only exists after ConfigurationManager has initialized its Settings scope; setting Theme before that would corrupt or lose the value, so it is rejected.

Source

Thrown at Terminal.Gui/Configuration/ThemeManager.cs:226

            if (ConfigurationManager.Settings is { } && ConfigurationManager.Settings.TryGetValue ("Theme", out ConfigProperty? themeCp))
            {
                if (themeCp.HasValue)
                {
                    return (themeCp.PropertyValue as string)!;
                }

                return DEFAULT_THEME_NAME;
            }

            throw new InvalidOperationException ("Settings is null.");
        }

        set
        {
            if (!ConfigurationManager.IsInitialized ())
            {
                throw new InvalidOperationException ("Theme cannot be set before ConfigurationManager is initialized.");
            }

            if (ConfigurationManager.Settings is null || !ConfigurationManager.Settings.TryGetValue ("Theme", out ConfigProperty? themeCp))
            {
                throw new InvalidOperationException ("Settings is null.");
            }

            if (themeCp is null || !themeCp.HasValue)
            {
                throw new InvalidOperationException ("Theme has no value.");
            }

            if (!ConfigurationManager.Settings.TryGetValue ("Themes", out ConfigProperty? themesCp))
            {
                throw new InvalidOperationException ("Settings has no Themes property.");
            }

            string previousThemeValue = GetCurrentThemeName ();

View on GitHub (pinned to 2e47b11478)

Solutions

  1. Move the ThemeManager.Theme assignment to after Application.Create().Init() (or after ConfigurationManager.Load/Initialize) in your startup sequence.
  2. Guard the assignment: 'if (ConfigurationManager.IsInitialized ()) ThemeManager.Theme = name; else defer it.'
  3. Set the theme via config JSON (the "Theme" property) instead of in code, so it is applied during initialization.

Example fix

// before - runs in a static ctor / before init
static MyApp () { ThemeManager.Theme = "Dark"; }

// after
IApplication app = Application.Create ().Init ();
ThemeManager.Theme = "Dark";
app.Run<MyWindow> ();
Defensive patterns

Strategy: validation

Validate before calling

// Guard theme assignment until ConfigurationManager is ready
if (ConfigurationManager.IsInitialized ())
    ThemeManager.Theme = themeName;
else
    _deferredTheme = themeName; // apply after Application.Create().Init()

Type guard

static bool CanSetTheme () => ConfigurationManager.IsInitialized ();

Try / catch

try { ThemeManager.Theme = name; }
catch (InvalidOperationException ex) when (ex.Message.Contains ("before ConfigurationManager is initialized"))
{ /* defer until init completes */ }

Prevention

When it happens

Trigger: Assigning ThemeManager.Theme = "..." from a static constructor, a module initializer, a PreInit hook, or any code that runs before Application.Create().Init() / ConfigurationManager.Load has executed.

Common situations: Calling ThemeManager.Theme in a static field initializer that runs before the app starts; in a library that is loaded but whose app hasn't booted Terminal.Gui yet; ordering bug where theming code runs before configuration load.

Related errors


AI-assisted analysis of tui-cs/Terminal.Gui@2e47b11478 (2026-08-13). Data as JSON: /api/errors/566ff1ac490345f2. Report an issue: GitHub.