[BUG] Skill and agent frontmatter hooks silently not firing (CLI, Windows)

Resolved 💬 3 comments Opened Mar 26, 2026 by ybadragon Closed Apr 6, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Hooks defined in YAML frontmatter of skills and agents (as documented in Hooks in skills and agents) are silently ignored. The same hook command works correctly when placed in the plugin's hooks/hooks.json.

What Should Happen?

Hooks defined in skill/agent frontmatter should be scoped to the component's lifecycle and fire when the component is active.

Error Messages/Logs

### Debug Log Evidence

Enabled debug logging (`/debug`) and reproduced. The logs show two distinct behaviors:

**Frontmatter hook (does NOT fire)** — skill with `PostToolUse` frontmatter hook is active, Edit tool is called:


Getting matching hook commands for PostToolUse with query: Edit
Found 6 hook matchers in settings          <-- only settings-based hooks searched
Matched 2 unique hooks for query "Edit"    <-- 0 from frontmatter
Hook PostToolUse:Edit (PostToolUse) success:
✓ Deploy parameters updated                <-- only post-creation-reminder.js ran
  Verify container_settings and keyvalue_pairs format


The matcher count (6) is **constant** throughout the session — it never increases when a skill with frontmatter hooks becomes active.

**Global hooks.json (DOES fire)** — after adding validate-azdp.js back to `hooks.json`, same Edit call:


Getting matching hook commands for PostToolUse with query: Edit
Found 7 hook matchers in settings          <-- count increased from 6 to 7
Matched 3 unique hooks for query "Edit"    <-- increased from 2 to 3
Hook PostToolUse:Edit (PostToolUse) error:
❌ azuredeployparameters.json must use correct schema, not Azure ARM schema
Hook PostToolUse:Edit (PostToolUse) success:
✓ Reminder hook ran successfully


The validate-azdp.js script correctly detected the schema violation and blocked the edit — but only when registered via `hooks.json`. The identical hook defined in skill frontmatter is never added to the matcher pool.

Steps to Reproduce

Minimal Reproduction

my-plugin/
├── .claude-plugin/
│   └── plugin.json
├── hooks/
│   ├── hooks.json              # Global hooks — these DO fire
│   └── scripts/
│       └── validate.js         # Validation script (exits 2 on failure)
├── skills/
│   └── my-skill/
│       └── SKILL.md            # Frontmatter hook — does NOT fire
└── agents/
    └── my-agent.md             # Frontmatter hook — does NOT fire

What the Hook Validates

The validate-azdp.js script reads the tool input from stdin (file path, old/new strings for Edit, content for Write), reconstructs the resulting file content, then validates the JSON structure. It checks for required sections, naming conventions, and correct nesting — exiting with code 2 on any violation.

A simplified valid file looks like this:

{
  "parameters": {
    "container_settings": {
      "value": {
        "image": "myregistry.azurecr.io/my-app:latest",
        "targetPort": 8080,
        "cpu": 0.5,
        "memory": "1.0Gi"
      }
    },
    "app_settings": {
      "value": {
        "keyvalue_pairs": [
          { "name": "MY_SETTING", "value": "some-value", "isSecret": false }
        ]
      }
    }
  }
}

The test file we used intentionally has multiple violations (wrong schema, missing required sections, invalid naming) so the script would exit 2 and block the edit if the hook actually fired.

Steps to Reproduce

Test 1: Skill frontmatter hook (PreToolUse)
---
name: azdp-test
description: "Test skill for modifying azuredeployparameters.json."
hooks:
  PreToolUse:
    - matcher: "Write|Edit"
      hooks:
        - type: command
          command: "node \"${CLAUDE_PLUGIN_ROOT}/hooks/scripts/validate-azdp.js\""
          timeout: 30
---

Add a test entry to azuredeployparameters.json.
  1. Invoke the skill: /platform:azdp-test
  2. Claude edits the file successfully — the hook never fires
Test 2: Skill frontmatter hook (PostToolUse)

Same skill, switched to PostToolUse. Same result — hook never fires.

Test 3: Agent frontmatter hook (PreToolUse)
---
name: azdp-test-agent
description: Test agent for modifying azuredeployparameters.json with hook validation.
tools: Read, Grep, Glob, Edit, Write
hooks:
  PreToolUse:
    - matcher: "Write|Edit"
      hooks:
        - type: command
          command: "node \"${CLAUDE_PLUGIN_ROOT}/hooks/scripts/validate-azdp.js\""
          timeout: 30
---

Add a test entry to azuredeployparameters.json.
  1. A skill launches this agent
  2. The agent edits the file successfully — the hook never fires
Control: Global hooks.json (both PreToolUse and PostToolUse work)

The exact same hook command fires correctly for both event types when defined in the plugin's hooks/hooks.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/scripts/validate-azdp.js\"",
            "timeout": 30
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/scripts/validate-azdp.js\"",
            "timeout": 30
          }
        ]
      }
    ]
  }
}

Both fire on every Write/Edit call. The issue is specific to frontmatter-defined hooks.

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.84

Platform

Google Vertex AI

Operating System

Windows

Terminal/Shell

Windows Terminal

Additional Information

Additional Context

  • Plugin is installed from a local marketplace via claude plugin install
  • Tested with and without disable-model-invocation: true on the skill
  • Tested skill-direct invocation and agent-spawned-from-skill invocation
  • Tested both PreToolUse and PostToolUse event types in frontmatter
  • No errors or warnings in CLI output or debug log
  • Related issue #30874 reports the opposite problem (skill hooks persisting after completion), confirming the feature works in some environments

View original on GitHub ↗

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