[BUG] Subagent frontmatter hooks: PreToolUse never fires on 2.1.258 (same hook in settings.json fires for the subagent)

Status Open
Reported on v2.1.258
Maintainer reply None cached
Activity 0 comments · opened Sep 20, 2026

Summary

A hooks: block in a custom agent's frontmatter (documented under "Lifecycle Hooks" on the sub-agents page) never fires on Claude Code 2.1.258 (Windows 11, Git Bash present). The identical hook placed in the project's .claude/settings.json fires for the same subagent's tool calls and denies as expected.

Repro

.claude/agents/probe-hook.md:

---
name: probe-hook
description: probe
disallowedTools: Write, Edit, Bash
hooks:
  PreToolUse:
    - matcher: "mcp__.*__get_top_folders"
      hooks:
        - type: command
          command: 'python C:/tmp/deny.py frontmatter'
---
Call get_user_info_whoami, then get_top_folders, and report ok/denied for each.

deny.py writes its stdin to a file and exits 2 with a message on stderr.

  1. claude -p "Launch the probe-hook subagent and relay its report" (any MCP server with those two tools; I used a local stdio server).
  2. Result: both calls succeed; no file written by the frontmatter hook; the agent's report contains no denial.
  3. Move the same hook into .claude/settings.json (PreToolUse, same matcher/command): the call is denied, stderr reaches the model, and the recorded stdin contains agent_type: "probe-hook", agent_id, tool_name, cwd, permission_mode.

Expected

Per the docs, frontmatter hooks are "scoped to this subagent's lifecycle" and should fire on the subagent's PreToolUse events.

Notes

  • Exec form vs shell form does not matter here; neither fires from frontmatter.
  • The settings-level hook works and carries agent_type, so scoping a plugin hook by agent is possible as a workaround, but it is session-wide.
  • Environment: Claude Code 2.1.258, Windows 11 Enterprise 10.0.26200, hooks run under Git Bash 5.3.

View original on GitHub ↗