TUI startup errors invisible — alt-screen tears down before user can read them #6
Closed
opened 2026-05-21 22:02:46 -07:00 by vh
·
1 comment
No Branch/Tag Specified
main
diag/r30-gap-injection-harness
diag/r30-phi0-step-response
diag/r29-pad-series
graphify-tooling
v0.22.3
v0.22.2
v0.22.1
v0.22.0
v0.21.20
v0.21.19
v0.21.18
v0.21.17
v0.21.16
v0.21.15
v0.21.14
v0.21.13
v0.21.12
v0.21.11
v0.21.10
v0.21.9
v0.21.8
v0.21.7
v0.21.6
v0.21.5
v0.21.4
v0.21.3
v0.21.2
v0.21.1
v0.21.0
v0.20.17
v0.20.16
v0.20.15
v0.20.14
v0.20.13
v0.20.12
v0.20.11
v0.20.10
v0.20.9
v0.20.8
v0.20.7
v0.20.6
v0.20.5
v0.20.4
v0.20.3
v0.20.2
v0.20.1
v0.20.0
v0.19.9
v0.19.8
v0.19.7
v0.19.6
v0.19.5
v0.19.4
v0.19.3
v0.19.2
v0.19.1
v0.19.0
v0.18.11
v0.18.10
v0.18.9
v0.18.8
v0.18.7
v0.18.6
v0.18.5
v0.18.4
v0.18.3
v0.18.2
v0.18.1
v0.18.0
v0.17.17
v0.17.16
v0.17.15
v0.17.14
v0.17.13
v0.17.12
v0.17.11
v0.17.10
v0.17.9
v0.17.8
v0.17.7
v0.17.6
v0.17.5
v0.17.4
v0.17.3
v0.17.2
v0.17.1
v0.17.0
v0.16.1
v0.16.0
v0.15.1
v0.15.0
v0.14.2
v0.14.1
v0.14.0
v0.13.0
v0.12.0
v0.11.0
v0.10.0
v0.9.0
v0.8.2
v0.8.1
v0.8.0
v0.7.1
v0.7.0
v0.6.5
v0.6.4
v0.6.3
v0.6.2
v0.6.1
v0.6.0
v0.5.1
v0.5.0
v0.4.1
v0.4.0
v0.3.0
v0.2.1
v0.2.0
v0.1.0
Labels
Clear labels
blocked-needs-contract
blocked-needs-dependency
bug
cli
documentation
duplicate
enhancement
invalid
needs-architect-decision
needs-info
needs-triage
observability
ready-for-agent
sse-client
task
tui
wontfix
Sleipnir refuses dispatch — issue-scoped contract missing
Sleipnir holds dispatch — INV-029 dependency-aware gate
Something is not working
Command-line surface (--send, --new, --session, etc.)
Docs / contract / spec work
Duplicate of another issue
New feature or improvement
Not a real issue
Escalated for a design call
More info required from reporter
Newly filed, not yet sorted
Log-pane / debug-surface work (persona, admin events, Bifrost, tools)
Gates AFK dispatch via Sleipnir (applied by /sleipnir-preflight)
SSE consumer module (src/ratatoskr/sse_client.py)
Implementation task
Textual app shell + presenters
Accepted as not-fixing
Milestone
No items
No Milestone
Projects
Clear projects
No projects
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: vh/ratatoskr#6
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem
When
ratatoskr.tui'son_mountencounters an error during session setup(
AgentNotFound,SessionApiFailed, network error duringcreate_session), it writes a labeled[error_kind] ...line to theRichLog widget and calls
self.exit(<code>). The Textual app exits, thealt-screen tears down, and the user is left looking at a blank terminal —
the labeled line was written to the RichLog widget which only exists inside
the alt-screen. Exit code is set correctly, but there's no visible
diagnostic.
Surfaced during manual smoke 2026-05-21:
ratatoskr --new --agent lofn(which hits the issue #5 bug, 422 from server) blanks the screen for ~200ms
then quits with exit code 20. No visible diagnostic; the operator's only
recourse is to re-run the same flow under
--send(which writes errors toreal stderr that survives) to see what happened.
The
--sendmode handles this class of error correctly: stderr labels goto real stderr, which is the operator's terminal directly, not the
alt-screen. The TUI's flow violates the "errors should be visible to the
user" expectation that
--sendupholds.Solution
Recommendation: Option A — move session-create out of
on_mountandinto
run_tui(sync, BEFORE App.run() opens the alt-screen). Surfaceerrors to stderr at the
run_tuilayer; only enter the alt-screen aftersession-create succeeds.
This aligns the TUI's startup-error UX with the CLI's: failures before the
event loop opens print to stderr; failures during streaming render in
the alt-screen (where mid-session errors per INV-008 already go).
Implementation shape:
RatatoskrApp.__init__gainssession_id/agent_idparameters (pre-resolved).
on_mountno longer creates the session; it just opens theAsyncClient and populates the identity widgets.
Alternative options considered + rejected:
app.run()returns non-zero.Requires the App to expose its log content after exit; relies on widget
content surviving teardown. Adds a post-exit dump step that feels like
workaround.
~/.cache/ratatoskr/last-error.log.Rejected per design-brief §8d ("no cross-process resume, no config dir").
Out of scope (this issue)
surface). Each side pane is its own issue.
RichLog and return to idle per INV-008's "errors don't exit the app"
contract; the user reads them in the TUI. Only startup-phase errors
need pre-alt-screen visibility.
Benefits
--sendtodiagnose. Fixes the "screen blanks then quits" UX surfaced 2026-05-21.
bugs) before the alt-screen masks them.
failures inside App.run() (mid-stream) → RichLog per INV-008.
Acceptance
run_tuiSTEPS expanded with the pre-App.run() session-resolve step;
RatatoskrApp.__init__signature widened;on_mountSTEPS narrowed to client-open + identity-widget-populate.TestAppMounttests no longer drive session-create throughon_mount(it's gone); newTestRunTuitests cover the pre-App.run()error paths via stderr capture.
ratatoskr --new --agent <nonexistent>produces a visible[agent_not_found]line on stderr; no screen-blanking artifact.Dependencies
ratatoskr.tuishell) — landed on main; this issue amends itscontract.
wrong-input flow for per-user agents becomes 422-from-server which #6
must surface. But #6 is independent in scope; either can land first.
Closed — shipped. TUI startup error visibility implemented via TDD, two Volva rounds (commit
804c2df). _resolve_then_run routes pre-flight errors to stderr BEFORE alt-screen opens.