Hooks format migration: confusing error messages and undocumented format change
Resolved 💬 2 comments Opened Jan 9, 2026 by mmarschall Closed Jan 9, 2026
Summary
When migrating settings.json hooks from an older format, the error messages are confusing and don't clearly explain what the new format should be.
Old format (no longer works)
{
"hooks": {
"Stop": [
{
"type": "command",
"command": "echo done"
}
]
}
}
Error received
Settings Error
/home/devuser/.claude/settings.json
└ hooks
└ Stop
└ 0
└ hooks: Expected array, but received undefined
Hooks use a new format with matchers. Example: {"PostToolUse": [{"matcher": {"tools":
["BashTool"]}, "hooks": [{"type": "command", "command": "echo Done"}]}]}
The problem
- The error says
hooks: Expected array, but received undefinedbut doesn't explain that the structure changed from flat to nested - The example shows
"matcher": {"tools": ["BashTool"]}(an object), but forStophooks the matcher should be an empty string"" - When I tried
"matcher": {}(empty object), got a different error:matcher: Expected string, but received object
Correct format (discovered through trial and error)
{
"hooks": {
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "echo done"
}
]
}
]
}
}
Suggestions
- Improve error message to show the exact expected structure for the hook type being configured
- Provide different examples for different hook types (PostToolUse vs Stop) since they have different matcher requirements
- Consider a migration tool or clearer migration guide for the hooks format change
Environment
- Claude Code CLI
- Running in Docker container
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗