debug-hooks

Systematic workflow for debugging Claude Code hooks.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "debug-hooks" with this command: npx skills add parcadei/continuous-claude-v3/parcadei-continuous-claude-v3-debug-hooks

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

  1. 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"'

  1. 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

  1. 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

  1. 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 });

  1. 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

Symptom Likely Cause Fix

Hook never runs Not registered in settings.json Add to correct event in settings

Hook runs but no output Detached spawn hiding errors Add logging, check manually

Wrong session ID Using "most recent" query Pass ID explicitly

Works locally, not in CI Missing dependencies Check npx/node availability

Runs twice Registered in both global + project Remove 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

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

github-search

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

dead-code

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

skill-development

No summary provided by upstream source.

Repository SourceNeeds Review