Skip to content

fix(shell): exit gracefully with crash report when CWD is removed during session#1622

Open
n-WN wants to merge 3 commits intoMoonshotAI:mainfrom
n-WN:fix/cwd-oserror-bottom-toolbar
Open

fix(shell): exit gracefully with crash report when CWD is removed during session#1622
n-WN wants to merge 3 commits intoMoonshotAI:mainfrom
n-WN:fix/cwd-oserror-bottom-toolbar

Conversation

@n-WN
Copy link
Copy Markdown
Collaborator

@n-WN n-WN commented Mar 28, 2026

Related Issue

Resolves #1621 — Infinite error cascade when working directory is removed (e.g. external drive unplugged).

Description

Root Cause

_render_bottom_toolbar() calls KaosPath.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() raises OSError: [Errno 2].

This triggers a cascade:

render cycle → KaosPath.cwd() → OSError
  → prompt_toolkit _handle_exception() → "Press ENTER to continue..."
    → _do_wait_for_enter() → new PromptSession → render cycle → KaosPath.cwd() → OSError
      → _handle_exception() → "Press ENTER to continue..."
        → ... (infinite loop)

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 with contextlib.suppress(Exception), but the toolbar CWD display is not.

Fix

prompt.pyCwdLostError + detection:

  • Add CwdLostError(OSError) exception class
  • Catch OSError at the KaosPath.cwd() call site in _render_bottom_toolbar
  • Call app.exit(exception=CwdLostError()) to cleanly terminate the prompt_toolkit application
  • Return an empty FormattedText so the current render frame completes without error

__init__.py — graceful exit with crash report:

  • Catch CwdLostError in _route_prompt_events, emit a cwd_lost event
  • Handle the event in the main shell loop: print a rich-formatted crash panel with session ID and working directory, then exit cleanly

Before / After

Before (v1.27.0) After (this branch)
Infinite error cascade, must force-kill Graceful crash panel, clean exit
before after

Key files changed

  • src/kimi_cli/ui/shell/prompt.pyCwdLostError class, catch OSError in _render_bottom_toolbar, exit prompt_toolkit app
  • src/kimi_cli/ui/shell/__init__.py_print_cwd_lost_crash() method, CwdLostError handling in event router and main loop
  • tests/ui_and_conv/test_shell_prompt_router.py — unit test for CwdLostError event routing

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked the related issue, if any.
  • I have added tests that prove my fix is effective or that my feature works.
  • I have run make gen-changelog to update the changelog.
  • I have run make gen-docs to update the user documentation.

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 2 additional findings.

Open in Devin Review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

# $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())
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已不存在此问题

…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
@n-WN n-WN force-pushed the fix/cwd-oserror-bottom-toolbar branch from 15b751a to 9894c4d Compare March 28, 2026 08:42
@n-WN n-WN changed the title fix: recover gracefully when CWD is removed during session fix(shell): exit gracefully with crash report when CWD is removed during session Mar 28, 2026
@n-WN n-WN force-pushed the fix/cwd-oserror-bottom-toolbar branch from 6a545bf to 68b738b Compare March 28, 2026 09:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant