Skip to content

bug: TUI shows a black screen after exiting a sandbox shell #2229

Description

@johntmyers

Agent Diagnostic

  • Skills loaded: tui-development, create-github-issue
  • OpenShell version tested: 0.0.82-dev.10+g40194f93 from current main (40194f93)
  • Latest release checked: v0.0.80 (published 2026-07-09)
  • Known fixes reviewed: reviewed recent TUI history, including fix(tui): route warning logs to status bar instead of stderr (#2210); the shell restoration sequence has been unchanged since the shell feature landed
  • Possible duplicates reviewed: searched all issues for TUI black screens, shell exit, alternate-screen restoration, and post-shell refresh behavior. Closed fix(tui): shell connect broken — wrong ssh-proxy CLI arguments after #175 rename #188 concerns incorrect SSH proxy arguments and is not a duplicate
  • Findings: reproduced on this Ubuntu host. After the remote exit, OpenShell re-enters and clears the alternate screen, then synchronously runs refresh_data() before the event loop can draw another frame. The refresh consists of several sequential gRPC calls with individual five-second timeouts, leaving an entirely black screen for approximately 20–30 seconds. Once the refresh finishes, the TUI redraws and responds normally
  • Remaining reason for filing: the blank screen looks like a terminal deadlock, accepts no visible interaction while refresh is running, and can cause users to kill the TTY even though the process eventually recovers

Description

Actual behavior: After opening a sandbox from openshell term, pressing s for a shell, and running exit, OpenShell switches back to an empty alternate screen. The screen remains black for roughly 20–30 seconds before the TUI eventually reappears. Users can reasonably interpret this as a hung terminal and kill the TTY.

Expected behavior: Exiting the sandbox shell should restore and draw the TUI immediately. Any gateway refresh should happen after a visible frame is rendered, preferably asynchronously without blocking input or rendering.

The current flow handles pending_shell_connect in crates/openshell-tui/src/lib.rs by awaiting handle_shell_connect(), then awaiting refresh_data(). handle_shell_connect() re-enters and clears the alternate screen before it returns. The event loop cannot draw until the synchronous refresh chain completes.

The terminal restoration operations (enable_raw_mode, EnterAlternateScreen, mouse capture, and terminal.clear) also discard errors with let _ = ..., which makes a genuine restoration failure indistinguishable from the refresh delay.

Reproduction Steps

  1. Run openshell term.
  2. Select a ready sandbox.
  3. Press s to open its interactive shell.
  4. Run exit.
  5. Observe that OpenShell enters a black alternate screen with no visible TUI or feedback.
  6. Wait approximately 20–30 seconds; the TUI eventually redraws and is responsive again.

Environment

Logs

The PTY output after exit stops immediately after alternate-screen entry and clear, with no frame content until the refresh completes:

exit
<leave bracketed paste mode>
exit
<enter alternate screen>
<enable mouse capture>
<clear screen>
... approximately 20–30 seconds with no output ...
<TUI frame is finally drawn>

Metadata

Metadata

Assignees

No one assigned

    Labels

    arch:arm64Bug affects arm64 architecturearea:tuiTerminal UI workos:linuxBug affects Linux hostsstate:agent-readyApproved for agent implementationstate:pr-openedPR has been opened for this issue

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions