github / github/copilot-cli

TUI wedges mid-turn (screen clears, input dead, Ctrl+C/Ctrl+\ ignored) — write EIO on stdout followed by EPIPE on Rust JSON-RPC transport; WSL2 + Windows Terminal

Đang mở
#4,069 7 bình luận 9 reaction 0 người được giao Xem trên GitHub
area:input-keyboard area:terminal-rendering
Ngôn ngữ chính
Shell
Star
11.2k
Fork
1.9k
Merge trung bình
14 giờ 16 phút
Pull request đã merge (30 ngày)
6

Mô tả

# Copilot CLI — mid-turn screen clear / unresponsive terminal

## Environment

- CLI version: `1.0.70-0`
- Node: `v24.11.1`
- OS: WSL2 (Ubuntu) on Windows 11
- Terminal: Windows Terminal
- Model in use: `claude-opus-4.7`

## Symptom

While the assistant is actively working in a session (streaming a reply and/or
running tools mid-turn), the CLI's terminal pane suddenly:

1. Clears to a blank alternate-screen buffer (just a cursor at column 0)
2. Stops rendering any further output
3. Stops accepting input — typing does nothing
4. Ignores `Ctrl+C` **and** `Ctrl+\` (SIGQUIT)
5. The underlying `copilot` node process remains alive; only tab-close /
external `kill -9` from another shell (or a reboot) recovers the terminal

Not idle-related. Reproduced within ~10 minutes of a fresh boot, mid-turn.
Multiple sessions in the same day exhibited it.

## What is NOT happening

- Not caused by leaving the CLI idle (initially suspected, ruled out — happens
mid-turn during active streaming/tool use).
- Not a terminal resize (no SIGWINCH in the timeline).
- Not user-initiated shutdown (no `Ctrl+D`, no `/exit`, no window close).

## Log signature

Recent process logs under `~/.copilot/logs/` for wedged sessions contain this
pattern around the point of failure:

```
[DEBUG] Ignoring transient stdout error: write EIO
[DEBUG] Uncaught Exception (transient I/O, suppressed): write EPIPE
Error: write EPIPE
[ERROR] Rust JSON-RPC transport error: Error: write EPIPE
...
[DEBUG] [shutdown] Starting dispose: InkInstance.rerender
[DEBUG] Ignoring transient stdout error: write EIO
[DEBUG] [shutdown] Completed dispose: InkInstance.rerender (65ms)
```

The `write EIO` on stdout and `write EPIPE` on the Rust JSON-RPC transport
cluster together, then Ink attempts a shutdown re-render. This looks like the
Ink renderer (or something writing to stdout in parallel with it) hits EIO,
which then cascades EPIPE across the extension-host IPC pipes. Because the
CLI classifies EIO as "transient" and does not abort, the process keeps
running with a dead TTY — no input handler, no visible output.

Contributing hypothesis: high re-render rate during streaming
(`assistant.streaming_delta` + `assistant.tool_call_delta` events) combined
with concurrent writers to stdout produces a short window where a write races
with something (terminal state change? SIGWINCH from Windows Terminal?
extension-host handshake?) and stdout returns EIO. Once stdout is EIO, Ink
can no longer paint and the input reader also stalls.

## Wedged process observations

Example: PID 2160 (`copilot`, pts/2), state `Sl+`, still alive over an hour
after the wedge. Log
`~/.copilot/logs/process-1783606860101-2160.log` shows normal activity, then
only ExP telemetry heartbeats every ~10 minutes — no user input events, no
render updates. Consistent with "TUI/input loop dead, background workers
alive."

## Impact

- Loss of the active turn's visible output (state is still on disk under
`~/.copilot/session-state//` and resumable, but the in-progress reply
is gone).
- Ctrl+C / Ctrl+\ ineffective — no graceful shutdown path from within the
wedged terminal.
- Requires killing the process from a separate shell, or a system reboot in
the worst case.

## Requested fixes / improvements

1. When stdout returns `EIO` repeatedly (say, more than N times in M ms),
treat it as fatal instead of transient. Either:
- attempt to reopen `/dev/tty` and re-attach Ink, or
- exit cleanly with a diagnostic message.
2. Ensure `Ctrl+C` and `Ctrl+\` remain honored even if the Ink render loop
is stalled — the SIGINT/SIGQUIT handler should not depend on the TUI
being alive.
3. Optional: a `COPILOT_NO_ALT_SCREEN=1` / `--no-alt-screen` escape hatch
that renders inline instead of using the alternate screen buffer, so a
wedge doesn't hide scrollback and leaves recovery affordances visible.
4. Investigate whether the extension-host EPIPE bursts (link-checker,
stale-content-finder, pr-review-feedback, crlf-guard, frontmatter-validator,
ms-date-auto-updater are all forked at startup on this system) contribute
by writing to shared stdio pipes during a render.

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Hướng nghiên cứu

Start by reproducing the mid-turn wedge in WSL2 with Windows Terminal while collecting the ~/.copilot/logs/ process log, then trace the stdout EIO handling, Ink shutdown re-render, and Rust JSON-RPC EPIPE sequence described here. Done should include a defined recovery or clean-exit behavior, with Ctrl+C and Ctrl+\\ still effective when rendering is stalled.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
node.js, rust
Lĩnh vực
cli
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Ít trao đổi
Độ rõ ràng
Cần làm rõ
Mức phù hợp với người mới
35/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.