github / github/copilot-cli

[BUG]: extensions_reload and extensions_manage tools deadlock permanently when project has a joinSession() extension

Đang mở
#2,348 0 bình luận 0 reaction 0 người được giao Xem trên GitHub
area:plugins
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ả

### Describe the bug

Calling `extensions_reload` or `extensions_manage` tools in a session where a project-level extension (using `joinSession()` from `@github/copilot-sdk/extension`) is active results in a permanent hang that requires the user to manually cancel the tool call. The CLI never recovers from the hang — the tool call must be interrupted every time.

### Root cause analysis

The deadlock is caused by a circular IPC dependency during the reload sequence:

1. `extensions_reload` is invoked → the CLI main process **blocks synchronously**, waiting for the reload to complete.
2. The existing extension subprocess is terminated.
3. A new `extension_bootstrap.mjs` subprocess is spawned and loads the extension module.
4. The extension module calls `await joinSession()` at the top level — this sends a handshake message **back to the CLI main process** to register tools and establish the session.
5. The CLI main process **cannot respond** to the handshake because it is blocked in step 1.
6. → **Permanent deadlock**: parent waits for child, child waits for parent.

The same deadlock occurs with `extensions_manage` because it goes through the same extension management subsystem.

### Affected version

GitHub Copilot CLI `1.0.12`

### Steps to reproduce

1. Create a project-level extension in `.github/extensions/my-ext/extension.mjs` with a top-level `await joinSession(...)` call (standard SDK pattern from the documentation).
2. Start a Copilot CLI session in that project directory. The extension loads successfully.
3. In the session, call the `extensions_reload` tool (or `extensions_manage` with operation `list`/`inspect`).
4. Observe: the tool call **never returns**. The CLI is permanently unresponsive until the tool call is manually cancelled.
5. Repeat step 3 after cancelling — same result every time.

### Expected behavior

- `extensions_reload` should complete successfully and the extension should be re-registered.
- If the reload mechanism requires a subprocess handshake, the main process should handle IPC messages asynchronously (non-blocking) during the reload wait, so the new extension subprocess can complete its `joinSession()` registration.

### Additional context

**Environment:**
- OS: Linux (Ubuntu)
- Copilot CLI version: `1.0.12`
- Extension type: project-level (`.github/extensions/`), JS/ESM, using `@github/copilot-sdk/extension`

**Workaround:**
- Skills and agent `.md` files are effective immediately on save (no reload needed).
- For changes to `extension.mjs` JS code: close the terminal and re-open a new session.

**Process evidence** (at time of hang):
```
# Two extension_bootstrap.mjs subprocesses observed — both blocked
PID 230448 EXTENSION_PATH=.github/extensions/my-ext/extension.mjs COPILOT_LOADER_PID=230374
PID 245405 EXTENSION_PATH=.github/extensions/my-ext/extension.mjs COPILOT_LOADER_PID=210913

# stdin/stdout of each subprocess are sockets (IPC channels), confirming the
# joinSession() handshake is attempted but the parent is not reading from them.
fd 0 -> socket:[...]
fd 1 -> socket:[...]
```

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

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

Đánh giá

Issue này chưa được đánh giá.

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.