claude-hooks-valid¶
Claude Code hooks.json must be valid JSON with proper hook configuration structure
Formerly known as hooks-json-valid. The legacy name still works in configs, --rule/--skip-rule, suppression comments, and baselines.
| Severity | error |
| Autofix | - |
| Since | v0.1.0 |
| Category | Hooks |
Claude Code model-change hooks PreModelSwitch and PostModelSwitch are
recognized alongside the existing events (available since Claude Code 2.1.251).
Why¶
A Claude Code hooks.json configures commands that run automatically on
agent events. Invalid JSON, unknown event types, or misconfigured handler
objects will cause hooks to fail silently — the command never runs and no
error is surfaced to the user. A bare NaN or Infinity anywhere in the
file counts as invalid JSON: Claude Code's parser rejects the whole file.
A legal numeric literal such as 1e400 in ignored extension metadata is
accepted, as are quoted strings containing the words NaN or Infinity.
The event names, the handler types (command, http, mcp_tool,
prompt, agent) and the per-handler fields checked here are Claude
Code's. Codex, Muse Code and Grok Build read the same nested shape with
vocabularies of their own, and Cursor reads a flat per-event list of
command and prompt entries; each host's files are validated by its own
rule — codex-hooks-valid,
muse-hooks-valid,
grok-hooks-valid and
cursor-hooks-valid.
This rule was called hooks-json-valid before that split. The old name
still works everywhere a rule is named — config, --rule/--skip-rule and
suppression comments — and resolves to this rule alone, so
hooks-json-valid: {enabled: false} in a Codex project no longer covers
Codex's hooks: configure codex-hooks-valid by its
own id. A baseline recorded under the old name keeps applying here: this
rule's messages are unchanged from the ones it recorded.
The checks that moved to codex-hooks-valid were
re-worded, and a hooks file's baseline fingerprint hashes the message text —
JSON carries no line numbers to hash instead. An old baseline therefore carries
over to that rule only for the four file-level verdicts whose wording survived;
its page lists them.
The commands themselves are scanned by
hooks-dangerous and, when you want every hook
reviewed rather than only the risky-looking ones,
hooks-prohibited.
Examples¶
Bad:
Good:
How to fix¶
Fix the structural issue identified in the violation message. Common
problems: event values must be arrays of config objects, each config
must have a hooks array, each handler needs a type field, and
type-specific fields (command, url, prompt) must match the
handler type.
Configuration¶
Run skillsaw explain claude-hooks-valid to see this documentation and the rule's effective configuration in your terminal.