Debugging Hook Failures
Troubleshoot common hook execution issues and learn best practices for reliable automation.
Common Failure Causes
Hooks fail for a handful of reasons:
- A non-zero exit code: tests failing or lint errors
- Exit code 127, "command not found": the command isn't installed or isn't on the agent's
PATH - In
before_doing: missing git credentials, no network, or uncommitted changes in the way - In
before_review: the GitHub CLI isn't installed or signed in (gh auth login) - Taking longer than the 600-second (10-minute) timeout: make the commands faster rather than dropping checks
- Empty variables: quote them, and export them when you test by hand
Reading the Error
The agent measures each hook's exit_code, output and duration_ms and sends them to Stride, for example as after_doing_result. If a result is missing, incomplete or failing, the call fails with HTTP 422, the task stays where it was, and the response says why:
{
"error": "after_doing is a blocking hook and failed with exit code 1. Fix the issues and try again.",
"hook": "after_doing",
"required_format": {
"after_doing_result": {
"exit_code": 0,
"output": "Hook execution output",
"duration_ms": 1234
}
}
}
The Stride plugin for Claude Code reports a failing hook with the command that failed and its output, and the stride:hook-diagnostician agent turns that output into a plan for fixing it.
Testing Hooks Locally
.stride.md is a Markdown file, not a shell script, so you can't source it. To test a hook, export the variables it uses and run each line of its section one at a time in the project root, checking the exit code after each:
export TASK_IDENTIFIER="W1"
export TASK_TITLE="Try the hooks"
export HOOK_NAME="after_doing"
mix test
echo "exit code: $?"
Never print .stride_auth.md while you debug: it holds your token.
When a Hook Can't Be Fixed Now
If a hook keeps failing for a reason outside the task, the agent can give the task back with POST /api/tasks/:id/unclaim and a reason. The task returns to Ready for later.
A failing after_goal keeps the goal out of Done until a passing report arrives or the five-minute grace window ends.
Best Practices
- Keep hooks fast, well under the 600-second limit
- Put one command on each line: the agent stops at the first one that fails
- Print meaningful output, so a failure explains itself
- Leave a section empty when it has nothing to do
- Check the review decision before merging or deploying in
after_review - Test hooks by hand before relying on them
You're all set!
You've completed all the steps in this guide.