Claude Code kept shipping broken code until I added this one automation

Claude Code kept shipping broken code until I added this one automation

Published Aug 26, 2026, 12:30 PM EDT Anurag is an experienced journalist and author who’s been covering tech for the past 5 years, with a focus on Windows, Android, and Apple. He’s written for sites like Android Police, Neowin, Dexerto, and MakeTechEasier. Anurag’s always pumped about tech and loves getting his hands on the latest gadgets. When he's not procrastinating, you’ll probably find him catching the newest movies in theaters or scrolling through Twitter from his bed. If you have used Claude Code to build anything, you've noticed that the safety net mostly comes from how you describe your prompt. If you tell the agent in your prompt to build something and test it, it will build and test. If you don't mention in your prompt whether testing is required, the model will assume it's not and mark the task as finished. You’ll then go through the results and ask it to test, and then it will test. At least this is how I have been dealing with Claude Code for the longest time. More recently, though, I discovered Claude hooks. These are lifecycle callbacks you can configure in Claude Code that run shell commands automatically at defined points in the agent loop. I configured one such hook that forces Claude Code to test everything before calling a task done, and it has been a lifesaver for me so far. Claude hooks is a godsend feature It saves so much time Hooks are entries in your Claude configuration that tell Claude Code to run a command when a specific event fires. This is your typical automation — how something would work in n8n or Home Assistant, where an action is triggered when a specific event happens. In the case of Claude Code, that event could be anything. For example, you could enable a hook to run when Claude executes a tool call. That could be before or after execution. What we are going to do for the purpose of this article is use Stop, which runs a command when an agent finishes a task. There could be a ton of other specific events. Each hook receives context about what Claude is about to do or just did. You can use that context to allow, block, or log the action. If a hook exits with a non-zero status, Claude treats it as a hard block and will not proceed. You could argue why go through the trouble of adding hooks when you can just add a simple line to your CLAUDE.md asking Claude to test the result before marking it complete? Well, you are right, but what you add in CLAUDE.md is a prompt instruction that can change depending on the context and how the model interprets it, while hooks are code that runs without fail. Claude Code now checks its responses And fixes its mistakes without me pointing them out As I mentioned, hooks can be added for any event, which means I can ask Claude to review its work before marking it complete. I don't want Claude to review every response because not everything needs reviewing. Sometimes I am just asking for a technical explanation or discussing an idea. I only want this check to run when Claude has finished a task, so instead of the more common "Stop" trigger, I use "TaskCompleted". I keep the hook inside the project under ".claude/hooks/" and use a small Bash script. The script moves into the current Claude Code project, runs "npm test", and checks the exit status. If the tests pass, it exits normally, and Claude can mark the task as complete. If they fail, the hook returns exit code "2", which blocks completion and sends the failed test output back to Claude. #!/usr/bin/env bash cat >/dev/null cd "$CLAUDE_PROJECT_DIR" || exit 2 OUTPUT_FILE="$(mktemp)" trap 'rm -f "$OUTPUT_FILE"' EXIT npm test >"$OUTPUT_FILE" 2>&1 TEST_STATUS=$? if [ "$TEST_STATUS" -eq 0 ]; then exit 0 fi echo "Tests failed. Fix the failures before marking this task complete." >&2 tail -n 200 "$OUTPUT_FILE" >&2 exit 2 The script must be executable, so run "chmod +x .claude/hooks/test-before-complete.sh" once after creating it. You can also test it manually by piping some empty JSON into it. If the project's tests pass, the script exits silently with status "0". The final step is registering it in ".claude/settings.json". I attach the script to the "TaskCompleted" event and give it enough time to finish running the test suite. { "env": { "CLAUDE_CODE_ENABLE_TODO_TOOLS": "1" }, "hooks": { "TaskCompleted": [ { "hooks": [ { "type": "command", "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/test-before-complete.sh", "args": [], "timeout": 600 } ] } ] } } The "CLAUDE_CODE_ENABLE_TODO_TOOLS" setting ensures Claude has access to task tools on models that don't expose them by default. Once this is in place, Claude finishes a task, the hook runs the test suite, and the task only gets marked complete if those tests pass. If something breaks, Claude gets the failure output and has to fix it before trying again. This can eat through your usage window, though And Claude Code's usage limit is already bad The usage limit you get with Claude Code is already abysmal, and it runs out pretty easily even during regular use. When you ask Claude Code to verify every completed task and reattempt it if the output isn't satisfactory, you'll eat through that usage window even faster. A failed test can send Claude back into the code, trigger more tool calls, and eventually run the hook again when it thinks the task is finished. If you use Claude Code to seriously ship something, I think that extra usage is worth the cost. I would rather spend a little more of my limit and know that the code at least passed the project's tests before Claude declared victory. It also saves me from having to manually check every task immediately after the agent finishes. For casual projects, though, I would not enable this everywhere. I would keep the hook for repositories where failed code actually matters and where I already have a useful test suite. Otherwise, you are spending tokens to verify work that probably did not need the extra pass in the first place. Claude Code can do so much for you Claude Code is capable of so much more than most people use it for, and if you're not getting the most out of this tool, you're probably using it wrong. Make sure you've added a proper claude.md file to your agent, and if you've already added one, make sure it's not bloated because that does more harm than good.

Original Source

Read the full article at Xda-developers →

KhanList aggregates and links to publicly available news content. We do not host full articles from third-party sources. Always verify important information with original sources.