github / github/copilot-cli

Hook `async` property silently ignored — postToolUse hooks block tool completion

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

The `async` property on command hooks in `hooks.json` is silently ignored. Hooks with `"async": true` still block tool completion because `executeHooks()` unconditionally `await`s every hook in a sequential `for` loop.

Claude Code [documents `async`](https://docs.anthropic.com/en/docs/claude-code/hooks) as a supported hook field:

> **`async`** — If `true`, runs in the background without blocking.

Since plugins share the same `hooks.json` format across both Claude Code and Copilot CLI, authors reasonably expect `"async": true` to work. Instead, it is parsed by the Zod schema (via `.passthrough()`) but never read by the execution path.

## Impact

In a real session, a `postToolUse` hook with `"async": true` blocked for **13.5 seconds** on first invocation because it triggered a package auto-update (resolving 419 packages via `uv`). This added ~14s of latency to the first tool call of the session despite the hook being marked async.

**Timeline from session events:**
```
18:57:09.756 hook.start postToolUse
18:57:22.186 [hook stdout] Resolved 419 packages in 6.91s
18:57:22.803 [hook stdout] Installed 2 packages
18:57:23.216 hook.end ← 13.46s blocked
```

## Root cause

In `sdk/index.js`, the `executeHooks` function (`Yg` in minified source):

```javascript
async function executeHooks(hooks, input, logger, hookType, emitter) {
// ...
for (let hook of hooks) {
let result = await hook(input); // ← always awaits, ignores async flag
// ...
}
}
```

And in `processToolExecutionResult`:
```javascript
await executeHooks(this.getEffectiveHooks()?.postToolUse, ...) // blocks tool completion
```

The `async` property from the hook config is never propagated to the execution layer.

## Expected behavior

When a hook specifies `"async": true`, it should run in the background without blocking tool completion — matching Claude Code's documented behavior. Ideally also support `asyncRewake` for parity.

## Workaround

Plugin authors can append `&` to the shell command to background it manually, but this loses stdout/stderr capture and exit code handling.

## Environment

- Copilot CLI: 1.0.40-2
- OS: macOS (Darwin arm64)

## Related issues

- #2893 — hooks serialized + timeout fail-open (related hook execution model concerns)

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

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

Hướng nghiên cứu

Start by tracing executeHooks in sdk/index.js and its call from processToolExecutionResult, then inspect how hook configuration reaches the execution layer. Confirm how async hooks should complete in the background and what output, errors, and tool completion should look like; done means async hooks no longer block while synchronous hooks retain their current behavior.

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
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
Khá rõ ràng
Mức phù hợp với người mới
48/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.