DEV Community

Jeremy Longshore
Jeremy Longshore

Posted on • Originally published at startaitools.com

Fixing Claude Code Hooks: The New Matcher Format

Claude Code recently changed their hooks format, and if you haven't updated your project settings, you'll see this cryptic error:

hooks: Expected array, but received undefined
Files with errors are skipped entirely, not just the invalid settings.
Enter fullscreen mode Exit fullscreen mode

The Problem

The old hook format put command at the top level:

{
  "hooks": {
    "Stop": [
      {
        "matcher": "",
        "command": "bash .claude/hooks/my-script.sh"
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

This silently breaks - your entire settings file gets skipped.

The Fix

The new format requires a nested hooks array with explicit type:

{
  "hooks": {
    "Stop": [
      {
        "matcher": ".*",
        "hooks": [
          {
            "type": "command",
            "command": "bash .claude/hooks/my-script.sh"
          }
        ]
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Key changes:

  1. matcher - Must be a valid regex (".*" matches everything, empty string doesn't work)
  2. hooks - Now an array inside the matcher object
  3. type - Required field, set to "command" for shell commands

Quick Migration

Find all your .claude/settings.json files and update them:

# Find all Claude settings files
find ~/projects -name "settings.json" -path "*/.claude/*" 2>/dev/null
Enter fullscreen mode Exit fullscreen mode

Then update each one to the new format.

Related

Top comments (0)