tui-cs/Terminal.Gui · error · ArgumentOutOfRangeException

Attempt to Run the runnable that's already the top runnable.

Error message

Attempt to Run the runnable that's already the top runnable.

What it means

Thrown by ApplicationImpl.Begin when the runnable being started is identical (reference-equal) to the runnable currently on top of the session stack (TopRunnable). Pushing the same runnable again would corrupt the stack and produce duplicate IsRunning transitions. This is an ArgumentOutOfRangeException on the runnable parameter.

Source

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

        // Ensure the mouse is ungrabbed
        Mouse.UngrabMouse ();

        Navigation?.SetFocused (null);

        IRunnable? previousTop = null;

        // CRITICAL SECTION - Atomic stack + cached state update
        lock (_sessionStackLock)
        {
            // Get the previous top BEFORE pushing new token
            if (SessionStack?.TryPeek (out SessionToken? previousToken) == true && previousToken.Runnable is { })
            {
                previousTop = previousToken.Runnable;
            }

            if (previousTop == runnable)
            {
                throw new ArgumentOutOfRangeException (nameof (runnable), runnable, @"Attempt to Run the runnable that's already the top runnable.");
            }

            // Push token onto SessionStack
            SessionStack?.Push (token);

            TopRunnable = runnable;

            // Update cached state atomically - IsRunning and IsModal are now consistent
            SessionBegun?.Invoke (this, new SessionTokenEventArgs (token));
            runnable.SetIsRunning (true);
            runnable.SetIsModal (true);

            // Previous top is no longer modal
            previousTop?.SetIsModal (false);
        }

        // END CRITICAL SECTION - IsRunning/IsModal now thread-safe

View on GitHub (pinned to 2e47b11478)

Solutions

  1. Before starting a runnable, verify it is not the current TopRunnable: check app.TopRunnable != runnable.
  2. End or RequestStop the current top session before re-running the same runnable.
  3. Use distinct runnable instances for nested modal flows rather than reusing the same object.

Example fix

// before
app.Run (sameRunnable); // already the top runnable

// after
if (app.TopRunnable != sameRunnable)
{
    app.Run (sameRunnable);
}
Defensive patterns

Strategy: validation

Validate before calling

if (app.TopRunnable != runnable)
{
    app.Run (runnable);
}

Type guard

static bool IsNotTopRunnable (IApplication app, IRunnable r) => app.TopRunnable != r;

Prevention

When it happens

Trigger: Calling Run (or Begin) on the same runnable that is already the TopRunnable, e.g. re-running the top Window without first ending its session; recursive dialog logic that re-launches the active top-level.

Common situations: Menu/shortcut handlers that re-invoke Run on the currently active top-level; event-driven code that re-enters a runnable; incorrect session management when chaining modal flows.

Related errors


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