Skip to main content
skill CX Codex

debug-hooks — Claude Code skill: what it does, how to install

Systematic debugging guide for Claude Code hooks when events fail to fire, run twice, or swallow runtime errors.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add parcadei/Continuous-Claude-v3 --skill debug-hooks -a claude-code
Open on GitHub

What debug-hooks does

The skill provides an inspection sequence for SessionEnd and PostToolUse hooks. It directs the agent to check outputs before modifying any code. Claude Code inspects the .claude/cache/ directory, checks debug logs, and inspects settings.json to find missing registrations or duplicate hooks.

To pinpoint failure points, the workflow pipes mock JSON payloads into shell wrappers. Silent failures often occur in detached spawns configured with stdio: 'ignore'. When that happens, the skill routes stdout and stderr into a temporary log file.

TypeScript source edits will not alter behavior immediately. The shell wrapper executes the bundled .mjs file in dist/. You must run an esbuild command after code modifications. The skill requires Bash, Read, and Grep tools.

What it helps with

  • identify why SessionEnd or PostToolUse hooks fail to trigger
  • test hook scripts manually with mock JSON payloads
  • capture silent failures hidden by detached spawn calls
  • fix duplicate hook runs caused by conflicting settings

Example prompts for the agent

  • My PostToolUse hook isn't firing, help me debug it
  • Check why the SessionEnd cleanup script produces no logs
  • Verify my hook registration in .claude/settings.json

How to install debug-hooks

1Skills CLI (Vercel)

npx skills add parcadei/Continuous-Claude-v3 --skill debug-hooks -a claude-code

2Manually: put the files in place

~/.claude/skills/debug-hooks/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/debug-hooks/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about debug-hooks

How to install debug-hooks in Claude Code?

Run npx skills add parcadei/Continuous-Claude-v3 --skill debug-hooks -a claude-code. You can also place the skill file directly at ~/.claude/skills/debug-hooks/SKILL.md.

What does debug-hooks do?

It runs a six-step diagnostic sequence for hook scripts. It verifies registration in settings.json, tests shell execution with mock JSON, and checks build outputs.

Why do TypeScript hook edits fail to take effect?

The hook executes a compiled bundle from .claude/hooks/dist/*.mjs. You must rebuild the source with esbuild before changes become active.

Source text

SKILL.md · MIT
---
name: debug-hooks
description: Systematic hook debugging workflow. Use when hooks aren't firing, producing wrong output, or behaving unexpectedly.
allowed-tools: [Bash, Read, Grep]
---

# 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)

```bash
# 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

```bash
# 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

```bash
# 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

```bash
# 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'`:

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

**Fix:** Add temporary logging:

```typescript
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:

```bash
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

© parcadei · MIT · parcadei/Continuous-Claude-v3

Similar skills

All skills for Agent setup: memory, context, orchestration →

From the same set69

compound-learnings Transforms ephemeral session learnings into permanent rules, skills, and hooks. It turns repeated coding patterns into lasting project capabilities. CX Codex +1 505installs hook-developer A reference for Claude hooks: input and output schemas, registration in settings.json, testing patterns. Handy when you are writing a hook and forgot the exact format. CX Codex +1 504installs tldr-code A skill that gives the agent tldr CLI commands for file trees, call graphs, data flow and dead code. Cheaper on tokens than reading whole files. CX Codex +1 503installs research-external External research workflow for libraries, docs, and 2024–2025 best practices without touching local repository files. Queries Perplexity, Nia Docs, and Firecrawl. CX Codex +1 501installs describe-pr Builds pull request descriptions from the repository template after reviewing changes and checks. Use it before updating a PR body with GitHub CLI. CX Codex +1 499installs commit This skill turns session changes into git commits, shows you the plan first, and keeps Claude's name out of the messages. Handy when an agent has piled up edits. CX Codex +1 499installs braintrust-tracing This skill explains how Claude Code sessions are traced in Braintrust and how to investigate sub-agent traces. Use it when hook events or spans need debugging. CX Codex +1 495installs workflow-router Picks the right specialist agent for your goal — research, planning, building or debugging — and allocates resources. Useful when you don't know where to start. CX Codex +1 495installs

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor