DE

A systematic debugging guide to resolve issues with Claude Code hooks not triggering or behaving unexpectedly.

Install

mkdir -p .claude/skills/debug-hooks && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/5275" && unzip -o skill.zip -d .claude/skills/debug-hooks && rm skill.zip

Installs to .claude/skills/debug-hooks

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Systematic hook debugging workflow. Use when hooks aren't firing, producing wrong output, or behaving unexpectedly.
115 chars✓ has a “when” trigger
Intermediate

Key capabilities

  • Check project and global cache directories for hook outputs
  • Verify hook registration in project and global settings.json files
  • Confirm the existence of hook shell wrappers and compiled bundles
  • Manually test SessionEnd and PostToolUse hooks with example JSON input
  • Identify and fix silent failures caused by detached spawn with 'stdio: ignore'
  • Rebuild TypeScript source files for hooks using esbuild

How it works

The skill provides a systematic workflow that involves checking cache outputs, verifying hook registration in settings files, confirming hook file existence, and manually testing hook execution.

Inputs & outputs

You give it
A description of a hook issue, such as 'Hook isn't firing' or 'Hook produces wrong output'
You get back
Diagnostic steps and commands to identify the root cause of the hook issue

When to use debug-hooks

  • Troubleshooting hooks that fail to trigger
  • Validating settings.json hook registration
  • Debugging output errors in PostToolUse hooks

About this skill

Debug Hooks

Systematic workflow for debugging Claude Code hooks.

When to Use

  • "Hook isn't firing"
  • "Hook produces wrong output"
  • "SessionEnd not working"
  • "PostToolUse hook not triggering"
  • "Why didn't my hook run?"

Workflow

1. Check Outputs First (Observe Before Editing)

# Check project cache
ls -la $CLAUDE_PROJECT_DIR/.claude/cache/

# Check specific outputs
ls -la $CLAUDE_PROJECT_DIR/.claude/cache/learnings/

# Check for debug logs
tail $CLAUDE_PROJECT_DIR/.claude/cache/*.log 2>/dev/null

# Also check global (common mistake: wrong path)
ls -la ~/.claude/cache/ 2>/dev/null

2. Verify Hook Registration

# Project settings
cat $CLAUDE_PROJECT_DIR/.claude/settings.json | grep -A 20 '"SessionEnd"\|"PostToolUse"\|"UserPromptSubmit"'

# Global settings (hooks merge from both)
cat ~/.claude/settings.json | grep -A 20 '"SessionEnd"\|"PostToolUse"\|"UserPromptSubmit"'

3. Check Hook Files Exist

# Shell wrappers
ls -la $CLAUDE_PROJECT_DIR/.claude/hooks/*.sh

# Compiled bundles (if using TypeScript)
ls -la $CLAUDE_PROJECT_DIR/.claude/hooks/dist/*.mjs

4. Test Hook Manually

# SessionEnd hook
echo '{"session_id": "test-123", "reason": "clear", "transcript_path": "/tmp/test"}' | \
  $CLAUDE_PROJECT_DIR/.claude/hooks/session-end-cleanup.sh

# PostToolUse hook (Write tool example)
echo '{"tool_name": "Write", "tool_input": {"file_path": "test.md"}, "session_id": "test-123"}' | \
  $CLAUDE_PROJECT_DIR/.claude/hooks/handoff-index.sh

5. Check for Silent Failures

If using detached spawn with stdio: 'ignore':

// This pattern hides errors!
spawn(cmd, args, { detached: true, stdio: 'ignore' })

Fix: Add temporary logging:

const logFile = fs.openSync('.claude/cache/debug.log', 'a');
spawn(cmd, args, {
  detached: true,
  stdio: ['ignore', logFile, logFile]  // capture stdout/stderr
});

6. Rebuild After Edits

If you edited TypeScript source, you MUST rebuild:

cd $CLAUDE_PROJECT_DIR/.claude/hooks
npx esbuild src/session-end-cleanup.ts \
  --bundle --platform=node --format=esm \
  --outfile=dist/session-end-cleanup.mjs

Source edits alone don't take effect - the shell wrapper runs the bundled .mjs.

Common Issues

SymptomLikely CauseFix
Hook never runsNot registered in settings.jsonAdd to correct event in settings
Hook runs but no outputDetached spawn hiding errorsAdd logging, check manually
Wrong session IDUsing "most recent" queryPass ID explicitly
Works locally, not in CIMissing dependenciesCheck npx/node availability
Runs twiceRegistered in both global + projectRemove duplicate

Debug Checklist

  • Outputs exist? (ls -la .claude/cache/)
  • Registered? (grep -A10 '"hooks"' .claude/settings.json)
  • Files exist? (ls .claude/hooks/*.sh)
  • Bundle current? (ls -la .claude/hooks/dist/)
  • Manual test works? (echo '{}' | ./hook.sh)
  • No silent failures? (check for stdio: 'ignore')

Source Sessions

Derived from 10 sessions (83% of all learnings):

  • a541f08a, 1c21e6c8, 6a9f2d7a, a8bd5cea, 2ca1a178, 657ce0b2, 3998f3a2, 2a829f12, 0b46cfd7, 862f6e2c

When not to use it

  • When hooks are firing correctly and producing expected output
  • When the issue is not related to hook registration or execution
  • When the problem is not with SessionEnd or PostToolUse hooks

Limitations

  • The skill focuses on debugging Claude Code hooks
  • The skill assumes the use of shell wrappers and potentially TypeScript compiled bundles
  • The skill provides fixes for issues related to detached spawn with 'stdio: ignore'

How it compares

This skill offers a structured, command-line driven diagnostic process for Claude Code hooks, unlike a manual trial-and-error approach.

Compared to similar skills

debug-hooks side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
debug-hooks (this skill)17moReviewIntermediate
n8n-expression-syntax64moNo flagsBeginner
python-repl64moReviewBeginner
n8n-validation-expert64moNo flagsIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

You might also like

n8n-expression-syntax

czlonkowski

Validate n8n expression syntax and fix common errors. Use when writing n8n expressions, using {{}} syntax, accessing $json/$node variables, troubleshooting expression errors, or working with webhook data in workflows.

6111

python-repl

gptme

Interactive Python REPL automation with common helpers and best practices

6102

n8n-validation-expert

czlonkowski

Interpret validation errors and guide fixing them. Use when encountering validation errors, validation warnings, false positives, operator structure issues, or need help understanding validation results. Also use when asking about validation profiles, error types, or the validation loop process.

697

powershell-windows

davila7

PowerShell Windows patterns. Critical pitfalls, operator syntax, error handling.

2379

bats

OleksandrKucherenko

Bash Automated Testing System (BATS) for TDD-style testing of shell scripts. Use when: (1) Writing unit or integration tests for Bash scripts, (2) Testing CLI tools or shell functions, (3) Setting up test infrastructure with setup/teardown hooks, (4) Mocking external commands (curl, git, docker), (5) Generating JUnit reports for CI/CD, (6) Debugging test failures or flaky tests, (7) Implementing test-driven development for shell scripts.

991

browser-daemon

noiv

Persistent browser automation via Playwright daemon. Keep a browser window open and send it commands (navigate, execute JS, inspect console). Perfect for interactive debugging, development, and testing web applications. Use when you need to interact with a browser repeatedly without opening/closing it.

587

Search skills

Search the agent skills registry