Hook errors for PreToolUse:Agent / PostToolUse:Agent surface cryptic "command not found" output

Resolved 💬 3 comments Opened Apr 19, 2026 by dalinaum Closed Apr 19, 2026

Summary

When a project-level hook is configured for the (formerly) Task tool with a command that is not resolvable on PATH, Claude Code surfaces two repeating entries per agent call:

⎿  PreToolUse:Agent hook error
⎿  Failed with non-blocking status code:
      /bin/sh: entire: command not found
⎿  PostToolUse:Agent hook error
⎿  Failed with non-blocking status code:
      /bin/sh: entire: command not found

There are a couple of things that make this worse than it needs to be:

  1. The hook matcher in settings is "Task" (matching Claude Code's documented tool name), but the error header reports the tool as Agent. This mismatch between the configured matcher and the reported tool name makes it non-obvious which hook entry is failing and which tool triggered it.
  2. The error is labelled "non-blocking status code", but each failing invocation still prints a multi-line error block in the transcript for every single Agent call, which is visually noisy and gives little actionable information (no hook index, no matcher, no command string).

Repro

.claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Task",
        "hooks": [
          { "type": "command", "command": "entire hooks claude-code pre-task" }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Task",
        "hooks": [
          { "type": "command", "command": "entire hooks claude-code post-task" }
        ]
      }
    ]
  }
}

With entire not installed / not on the hook process's PATH, any use of the agent tool produces the error shown above.

Expected

Either:

  • The hook error output includes the failing hook's matcher and the resolved command string, so the user can identify which hook to fix, or
  • The tool-name label in the error header uses the same identifier (Task vs Agent) that users are expected to put in matcher, so the config and the diagnostic stay in sync, or
  • Non-blocking hook failures are coalesced into a single warning per session rather than being repeated on every invocation.

Environment

  • Claude Code CLI (Opus 4.7, 1M context)
  • macOS (Darwin 25.2.0)
  • Non-login /bin/sh shell is used for hook execution, which does not source ~/.zshrc — tools installed only under a user-customized PATH (e.g. ~/.local/bin, asdf, homebrew cellar) will not be found even when the same command runs fine in the interactive shell.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗