fix(shell): exit gracefully with crash report when CWD is removed during session#1622
fix(shell): exit gracefully with crash report when CWD is removed during session#1622n-WN wants to merge 3 commits intoMoonshotAI:mainfrom
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 15b751a916
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
src/kimi_cli/ui/shell/prompt.py
Outdated
| # $HOME so that every subsequent getcwd() in the event loop (including | ||
| # prompt_toolkit's own error-recovery prompt) keeps working instead of | ||
| # cascading into an infinite "Unhandled exception" loop. | ||
| fallback = str(Path.home()) |
There was a problem hiding this comment.
Handle unresolved home dir in CWD fallback
If KaosPath.cwd() fails and this recovery branch runs, Path.home() can raise RuntimeError when ~ cannot be resolved (for example, stripped-down container users without a valid HOME/passwd entry). Because only OSError is handled here, that exception escapes and the toolbar redraw still crashes, reintroducing the repeated prompt_toolkit error loop this change is meant to avoid. Make the fallback path resolution exception-safe before calling os.chdir.
Useful? React with 👍 / 👎.
…sion When the working directory disappears (e.g. external drive unplugged), os.getcwd() raises OSError in the bottom toolbar render callback. Because prompt_toolkit's event loop catches unhandled exceptions and shows a "Press ENTER to continue..." prompt that itself triggers a redraw, this creates an infinite cascade of errors flooding the terminal. Fix by catching OSError at the KaosPath.cwd() call site in _render_bottom_toolbar and calling app.exit(exception=CwdLostError()) to cleanly terminate the prompt_toolkit application. The Shell event router then catches CwdLostError and prints a rich-formatted crash panel with session ID and working directory, so the user knows what happened and can resume. Closes MoonshotAI#1621
15b751a to
9894c4d
Compare
6a545bf to
68b738b
Compare
Related Issue
Resolves #1621 — Infinite error cascade when working directory is removed (e.g. external drive unplugged).
Description
Root Cause
_render_bottom_toolbar()callsKaosPath.cwd()→os.getcwd()on every render cycle to display the current working directory in the status bar. When the CWD no longer exists (external drive unplugged, directory deleted, filesystem unmounted),os.getcwd()raisesOSError: [Errno 2].This triggers a cascade:
prompt_toolkit's event loop catches unhandled exceptions and shows a "Press ENTER to continue..." prompt — but that prompt itself triggers a redraw, which calls
os.getcwd()again, creating an infinite error cascade that floods the terminal. The user must force-kill the process.Note: other CWD-dependent calls in the same file (
_get_git_branch(),_get_git_status()) are already wrapped withcontextlib.suppress(Exception), but the toolbar CWD display is not.Fix
prompt.py—CwdLostError+ detection:CwdLostError(OSError)exception classOSErrorat theKaosPath.cwd()call site in_render_bottom_toolbarapp.exit(exception=CwdLostError())to cleanly terminate the prompt_toolkit applicationFormattedTextso the current render frame completes without error__init__.py— graceful exit with crash report:CwdLostErrorin_route_prompt_events, emit acwd_losteventBefore / After
Key files changed
src/kimi_cli/ui/shell/prompt.py—CwdLostErrorclass, catchOSErrorin_render_bottom_toolbar, exit prompt_toolkit appsrc/kimi_cli/ui/shell/__init__.py—_print_cwd_lost_crash()method,CwdLostErrorhandling in event router and main looptests/ui_and_conv/test_shell_prompt_router.py— unit test forCwdLostErrorevent routingChecklist
make gen-changelogto update the changelog.make gen-docsto update the user documentation.