tui-cs/Terminal.Gui · error · ArgumentException

The runnable is already running.

Error message

The runnable is already running.

What it means

Thrown by ApplicationImpl.Begin(IRunnable) when runnable.IsRunning is already true. Begin is the low-level session-start API; it refuses to start a runnable that is already on the session stack. The higher-level Run API guards against this by reusing an existing token, so this exception surfaces when Begin is called directly on an active runnable.

Source

Thrown at Terminal.Gui/App/ApplicationImpl.Run.cs:118

                         {
                             action.Invoke ();

                             return false;
                         });
    }

    #endregion Timeouts and Invoke

    #region Session Lifecycle - Begin

    /// <inheritdoc/>
    public SessionToken? Begin (IRunnable runnable)
    {
        ArgumentNullException.ThrowIfNull (runnable);

        if (runnable.IsRunning)
        {
            throw new ArgumentException (@"The runnable is already running.", nameof (runnable));
        }

        // Create session token
        SessionToken token = new (runnable);

        Trace.Lifecycle (MainThreadId.ToString (), "Begin", "(token.Runnable as Runnable)?.ToIdentifyingString ()");

        // Get old IsRunning value BEFORE any stack changes (safe - cached value)
        bool oldIsRunning = runnable.IsRunning;

        // Raise IsRunningChanging OUTSIDE lock (false -> true) - can be canceled
        if (runnable.RaiseIsRunningChanging (oldIsRunning, true))
        {
            // Starting was canceled
            return null;
        }

        // Set the application reference in the runnable

View on GitHub (pinned to 2e47b11478)

Solutions

  1. Check runnable.IsRunning before calling Begin, and End the existing session first if you need to restart it.
  2. Prefer the higher-level Run/Run<T> API which already handles re-entrant runnables by reusing the existing token.
  3. Track the SessionToken returned by Begin and ensure End(token) is called before re-beginning.

Example fix

// before
app.Begin (runnable);
// ...
app.Begin (runnable); // throws — still running

// after
if (!runnable.IsRunning)
{
    app.Begin (runnable);
}
Defensive patterns

Strategy: validation

Validate before calling

if (!runnable.IsRunning)
{
    app.Begin (runnable);
}

Type guard

static bool CanBegin (IRunnable r) => !r.IsRunning;

Prevention

When it happens

Trigger: Calling app.Begin(runnable) on a runnable already returned by a prior Begin/Run that has not been Ended; manually calling Begin instead of Run and losing track of the session; nesting the same dialog without ending it first.

Common situations: Custom navigation logic that re-opens a modal Window/Dialog that is still running; event handlers that call Begin twice on the same object; misuse of the low-level Begin API when Run would have been correct.

Related errors


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