Skip to content

Hook async property silently ignored — postToolUse hooks block tool completion #3063

Description

@loganrosen

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 awaits every hook in a sequential for loop.

Claude Code documents async 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):

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:

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:pluginsPlugin system, marketplace, hooks, skills, extensions, and custom agentsarea:toolsBuilt-in tools: file editing, shell, search, LSP, git, and tool call behavior

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions