github / github/copilot-sdk

Extension command.execute can be accepted but never delivered, hanging slash-command invocation

Đang mở
#2,665 0 bình luận 0 reaction 0 người được giao Xem trên GitHub
bug runtime runtime triage
Ngôn ngữ chính
Java
Star
10.5k
Fork
1.5k
Merge trung bình
1 ngày 14 giờ
Pull request đã merge (30 ngày)
129

Mô tả

> Drafted by GIthub Copilot with human review.

## Summary

An extension slash command can be recognized by Copilot CLI and dispatched as `command.execute`, yet never reach the owning extension handler. The invocation then hangs silently because the runtime waits indefinitely for `session.commands.handlePendingCommand` and no timeout or delivery error is surfaced.

This is exposed through the public extension SDK, but the captured failure occurs in runtime command-event routing before SDK handler entry. Please triage as a runtime-root-cause bug.

## Environment

- Copilot CLI: `1.0.84-8`
- OS: Windows 11
- Extension API: `@github/copilot-sdk/extension` via `joinSession({ commands: [...] })`
- Reproduced: September 15, 2026

## Reproduction

1. Load an extension that registers a slash command through `joinSession`, for example:

```js
await joinSession({
commands: [{
name: "bookmarks",
description: "Open the session bookmark manager",
handler: async () => {
// Instrument handler entry here.
},
}],
});
```

2. Reload extensions.
3. Confirm the extension reaches `=== ready ===` and can service another registered callback. In this reproduction, its canvas provider successfully handled rehydration.
4. Invoke `/bookmarks` interactively.

## Actual behavior

- CLI recognizes and invokes the registered slash command.
- Runtime emits `command.execute` event ID `537170aa-2e69-41b6-a37b-ad0e505ea166`.
- The detached host-delivery queue starts and reports successful completion.
- The owning extension never enters the command handler.
- No `command.completed` event is emitted.
- No `No client found for command` error is emitted.
- The invocation remains pending indefinitely without user-visible failure.

Relevant runtime timeline:

```text
2026-09-15T08:44:56.142Z slash_command_invoked
2026-09-15T08:44:56.143Z Detached host delivery started
delivery_kind="reserved_event"
event_type="command.execute"
event_id="537170aa-2e69-41b6-a37b-ad0e505ea166"
2026-09-15T08:44:56.146Z Detached host delivery completed
2026-09-15T08:44:56.146Z Detached host delivery retirement decision completed
```

Temporary instrumentation around command-handler entry, `session.rpc.canvas.open`, and the canvas provider confirmed that neither the command handler nor downstream canvas call was reached. The same extension process had successfully handled canvas-provider rehydration approximately 35 seconds earlier.

## Expected behavior

One of the following should happen deterministically:

1. `command.execute` reaches the registered owner, the handler runs, and `command.completed` resolves the invocation; or
2. Delivery failure/disconnection is detected and the pending invocation fails promptly with an actionable error.

A request-like control-plane event must not be considered successfully delivered merely because it was queued somewhere that may never drain.

## Suspected runtime area

Runtime source currently:

- resolves a targeted owner for `command.execute`;
- calls `publish_session_event` for that connection;
- treats an event queued in `post_response_notifications` behind a `gated_sessions` dispatch token as successfully published; and
- waits on the pending command response without a timeout.

This makes a stale or unreleased create/resume response gate one plausible mechanism: publication reports success, so no undelivered-command rejection occurs, but the owner never receives the event. The logs do not expose the connection ID or gate token, so this is a hypothesis rather than a proven precise race.

## Relationship to #2368

This appears to be a sibling or incomplete-fix path for #2368, not necessarily the identical implementation defect:

- #2368 concerned lost `external_tool.requested` events and SDK event-forwarder lag.
- This reproduction concerns targeted `command.execute` delivery after extension reload.
- Both turn a lost request-like event into an indefinite hang because no timeout or disconnect failure resolves the pending request.

## Requested fix

- Guarantee delivery or explicit rejection for targeted `command.execute` events.
- Do not treat indefinitely gated notifications as successful delivery.
- Add a bounded timeout/disconnection failure for pending command execution as defense in depth.
- Add a regression test covering extension reload/resume followed by immediate slash-command invocation.

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

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

Hướng nghiên cứu

Bắt đầu từ đường dẫn định tuyến sự kiện lệnh của runtime, đặc biệt là việc phân giải owner được nhắm mục tiêu, publish_session_event, post_response_notifications, gated_sessions và quá trình chờ phản hồi lệnh đang chờ. Truy vết luồng reload/resume của extension và bổ sung phạm vi kiểm thử hồi quy được yêu cầu cho việc gọi lệnh slash ngay lập tức; được xem là hoàn tất khi command.execute đến được owner của nó và hoàn thành, hoặc khi lỗi phân phối được giải quyết kịp thời với một lỗi có thể hành động.

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

Đánh giá

Công nghệ
javascript
Lĩnh vực
backend-api-design, distributed-systems
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Sôi nổi
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
38/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.