feat(hook): say why a hook is invalid - #9699
Open
dadgrand wants to merge 1 commit into
Open
Conversation
`reasonix hook list --json` reports status "invalid" for five distinct
conditions without saying which one fired, so a misconfigured hook gives the
operator nothing to act on. The matcher branch is the clearest case: it calls
hook.ValidateMatcher, which already builds a full error message, and then
discards it.
Report the reason alongside the status:
unknown event "NotAnEvent"
command is required
contextFile "..." is not readable
plugin hook has neither a command nor a contextFile
invalid matcher regex: error parsing regexp: missing closing ): `^(?:()$`
This matters most when porting hooks from Claude Code, which the hook package
goes to some length to support elsewhere (tool-name aliases, PayloadFormat
"claude", CLAUDE_PROJECT_DIR). Claude's nested form —
{"matcher":"*","hooks":[{"type":"command","command":"..."}]}
— leaves Command empty, so it lands on the command check and now answers
"command is required" instead of a bare "invalid".
Active entries carry no reason, so existing consumers see an unchanged shape.
dadgrand
force-pushed
the
fix/hook-invalid-reason
branch
from
September 1, 2026 11:16
50f23c4 to
bf8bd15
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
reasonix hook list --jsonreports"status": "invalid"for five distinct conditions without saying which one fired, so a misconfigured hook gives the operator nothing to act on.hook.ValidateMatcher, which already builds a full error message, and then discards it.reason, so existing consumers see an unchanged shape.This matters most when porting hooks from Claude Code, which
internal/hookgoes to some length to support elsewhere — tool-name aliases across Claude renames (Task→Agent,BashOutput→TaskOutput),PayloadFormat "claude",CLAUDE_PROJECT_DIR/CLAUDE_PLUGIN_ROOT. Claude's nested form:{"matcher":"*","hooks":[{"type":"command","command":"…"}]}leaves
Commandempty, so it lands on the command check and now answerscommand is requiredinstead of a bareinvalid.Issues
Verification
go test ./...passes.gofmt -l .andgo vet ./...clean. Go 1.26.2, darwin/arm64.TestHookMachineEntryStatusRejectsNonRegularContextFileis updated for the two-value signature and still passes unchanged in intent.TestMachineHookEntryStatusExplainsEveryRejectioncovers unknown event, missing command and a malformed matcher regex;TestMachineHookEntryStatusLeavesActiveEntriesUnexplainedpins that an active entry emits noreason, so the JSON shape is unchanged for the common case.Documentation impact
Documentation-impact: none - additive, optional field on an existing diagnostics payload; no CLI, config, provider, permission or tool behavior changes.
Cache impact
Cache-impact: none -
hook list --jsonoutput never enters the provider request; no system prompt, memory prefix, tool schema, tool surface or provider serialization is touched.Cache-guard: not applicable - no cache-sensitive path is modified.
System-prompt-review: N/A