{"record":{"id":"3d89234de89a90db","repo":"tui-cs/Terminal.Gui","slug":"init-called-multiple-times-without-shutdown","errorCode":null,"errorMessage":"Init called multiple times without Shutdown","messagePattern":"Init called multiple times without Shutdown","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"critical","filePath":"Terminal.Gui/App/ApplicationImpl.Lifecycle.cs","lineNumber":29,"sourceCode":"    /// <inheritdoc/>\n    public int? MainThreadId { get; set; }\n\n    /// <inheritdoc/>\n    public bool Initialized { get; set; }\n\n    internal SynchronizationContext? SynchronizationContext { get; private set; }\n\n    /// <inheritdoc/>\n    public event EventHandler<EventArgs<bool>>? InitializedChanged;\n\n    /// <inheritdoc/>\n    public IApplication Init (string? driverName = null)\n    {\n        if (Initialized)\n        {\n            Logging.Error (\"Init called multiple times without shutdown, aborting.\");\n\n            throw new InvalidOperationException (\"Init called multiple times without Shutdown\");\n        }\n\n        MainThreadId = Thread.CurrentThread.ManagedThreadId;\n\n        Trace.Lifecycle (MainThreadId?.ToString (), \"Init\", $\"driverName: {driverName}\");\n\n        // In Application.Init(), before starting the input thread:\n        // Pre-warm the Wcwidth static cache to prevent ZeroTable._lookup race condition\n        // See: https://github.com/spectreconsole/wcwidth/issues/11\n        _ = UnicodeCalculator.GetWidth (new Rune ('A'));\n\n        // Thread-safe fence check: Ensure we're not mixing application models\n        // Use lock to make check-and-set atomic\n        lock (_modelUsageLock)\n        {\n            // If this is a legacy static instance and instance-based model was used, throw\n            if (this == _instance && ModelUsage == ApplicationModelUsage.InstanceBased)\n            {","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/tui-cs/Terminal.Gui/blob/2e47b11478db083499917f2ad27c34d30efb0df1/Terminal.Gui/App/ApplicationImpl.Lifecycle.cs#L11-L47","documentation":"Thrown by ApplicationImpl.Init when Initialized is already true, meaning the application was already initialized and never shut down/disposed. Terminal.Gui enforces a single Init per application instance; re-entering Init would corrupt driver state, the session stack, and synchronization context. Call Dispose (or the legacy Shutdown) before starting a fresh session, or create a new application instance with Application.Create().","triggerScenarios":"Calling app.Init() twice on the same IApplication; calling Application.Init() (legacy static) twice without Application.Shutdown(); reusing a static instance across test cases without reset; a using-block dispose that was skipped due to an earlier exception.","commonSituations":"Long-running daemon that tries to restart the TUI in-place; test harnesses that share state between tests; IDE hot-reload scenarios that re-run Main; mixing the legacy static model with code that assumes fresh state.","solutions":["Ensure every Init has a matching Dispose/Shutdown: use the using-pattern (using var app = Application.Create().Init();) so Dispose always runs.","For the legacy static model, call Application.Shutdown() before the next Application.Init().","In tests, call ApplicationImpl.ResetStateStatic() or the provided test reset helper between cases.","Create a new instance via Application.Create() for each independent session instead of re-initializing the same one."],"exampleFix":"// before\nvar app = Application.Create ().Init ();\n// ... later, same process ...\napp.Init (); // throws\n\n// after\nusing var app = Application.Create ().Init ();\napp.Run<MyWindow> ();\n// Dispose runs automatically; create a new instance for the next session.","handlingStrategy":"validation","validationCode":"if (app.Initialized)\n{\n    // already initialized; do not call Init again\n    return;\n}\napp.Init ();","typeGuard":"static bool IsAppReady (IApplication app) => app.Initialized;","tryCatchPattern":null,"preventionTips":["Always pair Init with Dispose/Shutdown; prefer the using-block pattern.","Use Application.Create().Init() chaining so each session is a fresh instance.","In tests, reset state with ApplicationImpl.ResetStateStatic() between cases."],"tags":["lifecycle","initialization","static-state"],"backgroundTag":null,"analyzedSha":"2e47b11478db083499917f2ad27c34d30efb0df1","analyzedAt":"2026-08-13T19:20:08.826Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}