tui-cs/Terminal.Gui · critical · InvalidOperationException

Cannot use modern instance-based model (Application.Create)

Error message

Cannot use modern instance-based model (Application.Create) after using legacy static Application model (Application.Init/ApplicationImpl.Instance). Use only one model per process.

What it means

Thrown by ApplicationImpl.MarkInstanceBasedModelUsed (called by Application.Create) when ModelUsage is already LegacyStatic and the legacy _instance is Initialized. This prevents switching to the modern model after the legacy static singleton has been brought up. Error string is ERROR_MODERN_AFTER_LEGACY. It is the mirror of error [4]/[10] at the Create() entry point.

Source

Thrown at Terminal.Gui/App/ApplicationImpl.cs:143

                // Mark the usage and create the instance
                ModelUsage = ApplicationModelUsage.LegacyStatic;

                return _instance = new ApplicationImpl ();
            }
        }
    }

    /// <summary>
    ///     INTERNAL: Marks that the instance-based model has been used. Called by Application.Create().
    /// </summary>
    internal static void MarkInstanceBasedModelUsed ()
    {
        lock (_modelUsageLock)
        {
            // Check if the legacy static model has already been initialized
            if (ModelUsage == ApplicationModelUsage.LegacyStatic && _instance?.Initialized == true)
            {
                throw new InvalidOperationException (ERROR_MODERN_AFTER_LEGACY);
            }

            ModelUsage = ApplicationModelUsage.InstanceBased;
        }
    }

    /// <summary>
    ///     INTERNAL: Resets the model usage tracking. Only for testing purposes.
    /// </summary>
    internal static void ResetModelUsageTracking ()
    {
        lock (_modelUsageLock)
        {
            ModelUsage = ApplicationModelUsage.None;
            _instance = null;
        }
    }

View on GitHub (pinned to 2e47b11478)

Solutions

  1. Use only one model per process; if legacy static was used, stay with it.
  2. Reset the fence in tests with ApplicationImpl.ResetModelUsageTracking() (test-only) before switching models.
  3. Ensure Application.Shutdown()/Dispose fully tears down the legacy instance before attempting Create (though mixing is still disallowed in one process).
  4. Run the conflicting model in a separate process.

Example fix

// before
Application.Init ();
using var app = Application.Create (); // MarkInstanceBasedModelUsed throws

// after — choose one model
using var app = Application.Create ().Init ();
Defensive patterns

Strategy: validation

Validate before calling

// Call Application.Create() before any Application.Init() in the process.
// Do not switch models mid-process.

Prevention

When it happens

Trigger: Calling Application.Create() after Application.Init() (legacy) already initialized the singleton; any code path that reaches MarkInstanceBasedModelUsed after the legacy model is live.

Common situations: Migrating mid-session from legacy to modern model; a startup sequence that calls Application.Init then later tries Application.Create; test code mixing both models without resetting the fence.

Related errors


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