tui-cs/Terminal.Gui · error · ApplicationException

Failed to restore output console mode, error code: {GetLastE

Error message

Failed to restore output console mode, error code: {GetLastError()}.

What it means

This error is thrown by NetWinVTConsole.Cleanup() when SetConsoleMode fails while restoring the original output console mode during teardown. This is the last step of Cleanup -- after flushing input and restoring input mode -- to return ENABLE_VIRTUAL_TERMINAL_PROCESSING to its original state. Failure leaves the console with VT processing enabled after exit.

Source

Thrown at Terminal.Gui/Drivers/WindowsHelpers/NetWinVTConsole.cs:91

            }
        }
    }

    public void Cleanup ()
    {
        if (!FlushConsoleInputBuffer (_inputHandle))
        {
            throw new ApplicationException ($"Failed to flush input queue, error code: {GetLastError ()}.");
        }

        if (!SetConsoleMode (_inputHandle, _originalInputConsoleMode))
        {
            throw new ApplicationException ($"Failed to restore input console mode, error code: {GetLastError ()}.");
        }

        if (!SetConsoleMode (_outputHandle, _originalOutputConsoleMode))
        {
            throw new ApplicationException ($"Failed to restore output console mode, error code: {GetLastError ()}.");
        }
    }

    [DllImport ("kernel32.dll")]
    private static extern bool GetConsoleMode (nint hConsoleHandle, out uint lpMode);

    [DllImport ("kernel32.dll")]
    private static extern uint GetLastError ();

    [DllImport ("kernel32.dll", SetLastError = true)]
    private static extern nint GetStdHandle (int nStdHandle);

    [DllImport ("kernel32.dll")]
    private static extern bool SetConsoleMode (nint hConsoleHandle, uint dwMode);

    [DllImport ("kernel32.dll", SetLastError = true)]
    private static extern bool FlushConsoleInputBuffer (nint hConsoleInput);
}

View on GitHub (pinned to 2e47b11478)

Solutions

  1. Use using/Dispose for normal teardown so Cleanup runs in the correct sequence.
  2. Avoid closing the console window abruptly; exit via the app's quit mechanism.
  3. Guard disposal in a try/catch in environments where console state is not critical (headless tests) to avoid masking errors.
  4. Ensure stdout is not redirected or closed during the session.

Example fix

// before -- crash leaves VT output enabled
app.Run<MyWindow>();
// process exits without cleanup

// after -- Dispose restores the original output mode
using (IApplication app = Application.Create().Init()) { app.Run<MyWindow>(); }
Defensive patterns

Strategy: try-catch

Try / catch

try { app.Dispose(); }
catch (ApplicationException ex) when (ex.Message.Contains("restore output console mode"))
{ Logging.Warning($"Console cleanup warning: {ex.Message}"); }

Prevention

When it happens

Trigger: Thrown at NetWinVTConsole.cs:91 when SetConsoleMode(_outputHandle, _originalOutputConsoleMode) returns false during Cleanup(). The output handle has become invalid or the console was detached.

Common situations: Console window closed while the app ran, stdout redirected or closed before teardown, process crash during shutdown, or IDE/debugger altering the output handle.

Related errors


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