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
- Use only one model per process; if legacy static was used, stay with it.
- Reset the fence in tests with ApplicationImpl.ResetModelUsageTracking() (test-only) before switching models.
- Ensure Application.Shutdown()/Dispose fully tears down the legacy instance before attempting Create (though mixing is still disallowed in one process).
- 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
- Decide on one model at startup and stick with it.
- Reset the fence only in tests via ApplicationImpl.ResetModelUsageTracking().
- Never call Application.Create after Application.Init in the same process.
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
- Cannot use legacy static Application model (Application.Init
- Cannot use modern instance-based model (Application.Create)
- Cannot use legacy static Application model (Application.Init
- Init called multiple times without Shutdown
- DefaultKeyBindings dictionary is null. Initialize it before
AI-assisted analysis of tui-cs/Terminal.Gui@2e47b11478 (2026-08-13).
Data as JSON: /api/errors/4210ee82ba498edd.
Report an issue: GitHub.