Hooks not executing despite following documentation

Status Fixed / completed
Maintainer reply ✓ Yes — dicksontsai
Activity 11 comments · opened Jul 2, 2025 · closed Jan 15, 2026
💡 Likely answer: A maintainer (dicksontsai, collaborator) responded on this thread — see the highlighted reply below.

Hook Functionality Verification Report

Environment

  • Claude Code Version: 0.10.14 (from ps output)
  • OS: Ubuntu 24.04.2 LTS
  • Date: 2025-07-02

Test Methodology

1. Hook Setup

Created executable hook scripts in ~/.claude/hooks/:

  • pre-tool (chmod +x)
  • post-tool (chmod +x)
  • pre-edit (chmod +x)

Each hook logs to /tmp/claude_hooks_*.log when executed.

2. Configuration

Added hook configuration to ~/.claude/settings.json:

{
    "hooks": {
        "PreToolUse": [
            {
                "matcher": "",
                "hooks": [
                    {
                        "type": "command",
                        "command": "~/.claude/hooks/pre-tool"
                    }
                ]
            }
        ],
        "PostToolUse": [
            {
                "matcher": "",
                "hooks": [
                    {
                        "type": "command",
                        "command": "~/.claude/hooks/post-tool"
                    }
                ]
            }
        ]
    }
}

3. Tests Performed

  1. Multiple Bash commands executed
  2. File creation using Write tool
  3. File editing using Edit tool
  4. Checked for log files after each operation

4. Results

  • No log files created in /tmp/claude_hooks_*.log
  • Manual execution of hooks works correctly
  • Hooks do not appear to execute automatically during tool use

Observations

  • Claude Code process running with flags: --dangerously-skip-permissions --mcp-config "/home/graham/.claude/claude_code/.mcp.json" --continue
  • No hook-related processes detected during tool execution
  • Settings file is valid JSON and readable

Questions

  1. Are there additional configuration steps required to enable hooks?
  2. Is there a specific flag needed when launching Claude Code?
  3. Are hooks only available in certain versions or editions?

Reproduction Steps

  1. Create hook script: echo '#!/bin/bash\necho "Hook executed" > /tmp/hook_test.log' > ~/.claude/hooks/pre-tool && chmod +x ~/.claude/hooks/pre-tool
  2. Configure in ~/.claude/settings.json as shown above
  3. Execute any Bash command through Claude Code
  4. Check for /tmp/hook_test.log - file is not created

Would appreciate clarification on whether hooks are currently functional and if there are additional setup requirements.

View original on GitHub ↗

11 Comments

grahama1970 · 1 year ago

Update: Tested suggested fixes - hooks still not executing

Thank you for the configuration feedback. I've implemented all suggested changes:

Changes Made:

  1. Fixed tilde expansion: Changed all hook paths from ~/.claude/hooks/pre-tool to absolute paths /home/graham/.claude/hooks/pre-tool
  2. Verified JSON validity: Both settings files pass python3 -m json.tool validation
  3. Added project-level settings: Created .claude/settings.json in the project directory
  4. Checked hook permissions: All scripts are executable (-rwxrwxr-x)

Additional Testing:

  • Attempted to run /hooks command as suggested - command not found
  • Monitored process list during tool execution - no hook processes spawn
  • Checked multiple locations for log files - none created

Current Configuration:

{
    "hooks": {
        "PreToolUse": [
            {
                "matcher": "",
                "hooks": [
                    {
                        "type": "command",
                        "command": "/home/graham/.claude/hooks/pre-tool"
                    }
                ]
            }
        ],
        "PostToolUse": [
            {
                "matcher": "",
                "hooks": [
                    {
                        "type": "command",
                        "command": "/home/graham/.claude/hooks/post-tool"
                    }
                ]
            }
        ]
    }
}

Result:

Despite implementing all suggested fixes, hooks still do not execute. No logs are created, no processes spawn, and the /hooks command mentioned in the documentation does not exist in my Claude Code installation.

Could this be a version-specific issue? The /hooks slash command doesn't appear to be available in version 0.10.14.

grahama1970 · 1 year ago

Workaround Solution

Since Claude Code hooks are not executing, here's a workaround that ensures deterministic hook execution:

Simple Python-based approach:

Instead of relying on Claude Code's hook system, modify your application to run hooks before launching subprocesses:

# In your subprocess launcher:
if "claude" in command.lower():
    # 1. Run hook scripts first
    subprocess.run([sys.executable, "hooks/setup_environment.py"], check=True)
    subprocess.run([sys.executable, "hooks/pre_check.py"], check=True)
    
    # 2. Setup environment for subprocess
    env = os.environ.copy()
    env["VIRTUAL_ENV"] = str(venv_path)
    env["PATH"] = f"{venv_path}/bin:" + env["PATH"]
    
    # 3. Launch subprocess with modified environment
    process = subprocess.run(command, env=env)

This approach:

  • Runs hooks deterministically (not dependent on Claude's cooperation)
  • Ensures subprocess inherits the correct environment
  • Works around the non-functional Claude Code hook system

The key insight from perplexity: Don't overcomplicate with wrapper scripts. Just run hooks in Python and pass the modified environment to subprocess via the env parameter.

### Temporary Workaround

Instead of relying on Claude Code to run hooks, I intercept
commands before they're executed and run the hooks
programmatically:

```python
# In websocket_handler.py or wherever you launch Claude
if "claude" in command.lower():
# Run pre-execution hooks directly
hooks_dir = Path.home() / ".claude" / "hooks"
for hook in ["pre-tool", "setup_environment.py"]:
hook_path = hooks_dir / hook
if hook_path.exists():
subprocess.run([sys.executable, str(hook_path)],
check=True)

# Setup environment for subprocess
env = os.environ.copy()
venv_path = Path(".venv")
if venv_path.exists():
env["VIRTUAL_ENV"] = str(venv_path)
env["PATH"] = f"{venv_path}/bin:" + env["PATH"]

# Execute with modified environment
result = subprocess.run(command, env=env, shell=True)

Test Results

From my testing, this approach seems to work with:

  • ✅ Simple commands (e.g., "What is 2+2?")
  • ✅ Medium tasks (e.g., "Write 5 haikus")
  • ✅ Long-running tasks (3-5 minute story generation)

All three test cases showed:

  • Pre-execution hooks ran successfully (environment setup,

dependency checks)

  • Virtual environment was properly activated
  • Post-execution hooks ran successfully (metrics recording,

output validation)

Why I Think This Works

This approach seems to bypass the Claude Code hook system
entirely by:

  1. Running hooks directly via subprocess before Claude starts
  2. Modifying the environment at the OS level
  3. Ensuring every Claude instance inherits the configured

environment

The hooks execute deterministically because they run before the
subprocess starts, not relying on the AI's voluntary compliance.

This workaround is keeping me unblocked for now, but it's
definitely not ideal. I hope for a proper working solution using claude code hooks.

Note: I could simply be doing this wrong, and would love to be corrected.
Adding determinism (pre and post) is crucial to an agent that simply forgets or refuses to follow instructions.

dicksontsai collaborator · 1 year ago

You can use claude --debug to look at whether Claude is picking up your hooks. You should see output like the following if there's a match.

[DEBUG] Executing hooks for PostToolUse:Edit
[DEBUG] Getting matching hook commands for PostToolUse with query: Edit
[DEBUG] Found 2 hook matchers in settings
[DEBUG] Matched 2 hooks for query "Edit"
[DEBUG] Found 2 hook commands to execute

Another thing you can try is to add a hook manually with /hooks and see if the same user-level settings file gets edited.

grahama1970 · 1 year ago

Thanks. I gave it shot... https://github.com/grahama1970/claude-code-hooks-test. As of yet, I can't get hooks to work reliably.
I 'think' it has something to do with me using --dangerously-skip-permissions. Not using the parameter would be a deal breaker for me.
On a positive note, this alternative is nearly complete: https://github.com/grahama1970/cc_executor, which might solve my immediate issues with hooks, and other challenges.

Maybe, on your end, you have a proof of concept example that tests a moderately complex example over 10x times to prove that Anthropic hooks are deterministic (work 100% of the time) and NOT agent optional? That would be lovely and helpful to many here with similar issues, I presume.

Onward and upwards

Rokurolize · 1 year ago

To utilize hooks, you must use a version of Claude Code that includes hook support. Hooks were first introduced in version 1.0.38 released on July 1, 2025 (https://github.com/anthropics/claude-code/commit/390f11039c4986f2172aae21c6380d2b5a8b251e), with the current latest version as of July 15, 2025 being 1.0.51. To update, install Claude Code using the command: npm install -g @anthropic-ai/claude-code.

dicksontsai collaborator · 1 year ago

FWIW I cloned your github repo and got the following output with --dangerously-skip-permissions. I did remove the loguru lines.

PreToolUse:Write [./hooks/pre_hook.py] completed successfully: Pre hook executed. Count: 2
[HOOK-PRE] Tool: None, PID: 9332, Time: 2025-08-23T11:53:33.122354

Running PostToolUse:Write...

PostToolUse:Write [./hooks/post_hook.py] completed successfully: Post hook executed. Count: 2
[HOOK-POST] Tool: None, PID: 9378, Time: 2025-08-23T11:53:33.188664

11:53

I wonder if there's something related to your shell setup.

github-actions[bot] · 8 months ago

This issue has been inactive for 30 days. If the issue is still occurring, please comment to let us know. Otherwise, this issue will be automatically closed in 30 days for housekeeping purposes.

jordangarside · 8 months ago

~Hooks don’t work for me at all on macOS Tahoe 26.1, claude code 2.0.69 installed with the bash script.
Tried uninstall/reinstalling claude code and still didn’t fix.~

Turns out they just don’t work from the home directory.

drouleau-gtvr · 7 months ago

this is done on the latest version of claude.code Claude Code v2.1.4
▝▜█████▛▘ Sonnet 4.5 · Claude Max
update # Bug Report: Claude Code Hooks Not Triggering Automatically

Date: 2026-01-11
Claude Code Version: CLI
Environment: Ubuntu 22.04
Severity: Medium - Feature Not Working

Issue Description

Hooks configured in .claude/settings.json do not trigger automatically despite correct and validated configuration.

Configuration Tested

.claude/settings.json

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": ".claude/hooks/check-standards.sh"
          }
        ]
      }
    ],
    "Stop": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": ".claude/hooks/final-check.sh"
          }
        ]
      }
    ]
  }
}

Hook Script (Works Manually)

#!/bin/bash
# check-standards.sh - Reads JSON from stdin
JSON_INPUT=$(cat)
FILE_PATH=$(echo "$JSON_INPUT" | jq -r '.tool_input.file_path // empty')
# ... hardcoded values detection ...

Tests Performed

✅ Manual Test (Works)

echo '{"tool_input":{"file_path":"/mnt/erp-core/erp-api/test-hook.py"}}' | .claude/hooks/check-standards.sh
# Result: ✅ Correctly detects errors (hardcoded values, URLs, etc.)

❌ Automatic Test (Does NOT Work)

  1. PostToolUse Test (Edit):
  • File created: /mnt/erp-core/erp-api/test-hook.py with hardcoded errors
  • Action: Edit on this file via Claude Code
  • Result: ❌ No hook triggered, no errors displayed
  1. PostToolUse Test (Write):
  • Action: Write a new .py file
  • Result: ❌ No hook triggered
  1. Stop Test:
  • Action: End of Claude response after modification
  • Result: ❌ Hook final-check.sh not executed

Environment Verified

  • ✅ Working directory: /mnt/erp-core (correct)
  • ✅ File .claude/settings.json present and valid
  • ✅ Hook scripts executable (chmod +x)
  • jq installed for JSON parsing
  • ✅ Relative AND absolute paths tested (none work)
  • ✅ Simplified matchers tested (Edit|Write, *)

Alternative Configurations Tested

| Configuration | Result |
|---------------|--------|
| Matcher: Edit:*.py\|Write:*.py | ❌ Doesn't work |
| Matcher: Edit\|Write | ❌ Doesn't work |
| Relative path: .claude/hooks/... | ❌ Doesn't work |
| Absolute path: /mnt/erp-core/.claude/hooks/... | ❌ Doesn't work |

Expected Behavior

When Edit or Write is performed on a .py, .js, or .jsx file:

  1. Claude Code should automatically execute the hook
  2. Hook receives JSON via stdin with tool_input.file_path
  3. Hook analyzes the file and returns exit 0 (OK) or exit 1 (errors)
  4. If exit 1, Claude should be blocked or warned

Actual Behavior

  • No hooks trigger automatically
  • No errors displayed in logs
  • Hooks work perfectly when executed manually

Current Workaround

Added to CLAUDE.md:

## MANDATORY
After each Edit/Write on .py/.jsx/.js, immediately execute:
.claude/hooks/check-standards.sh python   # for .py
.claude/hooks/check-standards.sh javascript   # for .jsx/.js

Claude must manually execute the hook via Bash after each modification.

Impact

  • Loss of automation - Agent must remember to execute hooks manually
  • Risk of oversight - Errors not detected if hook forgotten
  • Degraded experience - Hook system is unusable

Questions

  1. Are PostToolUse and Stop hooks supported in Claude Code CLI?
  2. Is there additional activation/configuration required?
  3. Do hooks only work in Claude web interface?
  4. Are there debug logs to see why hooks aren't triggering?

Request

  • Clear documentation on hook support in Claude Code CLI
  • If bug: fix to enable automatic hooks
  • If limitation: alternative or workaround documentation

Logs/Traces

No hook execution traces in:

  • /tmp/claude* (temporary files)
  • Standard output during Edit/Write
  • Env vars: CLAUDECODE=1 present

---

Reproducible: 100%
Contact: Via GitHub Issues https://github.com/anthropics/claude-code/issues

dicksontsai collaborator · 7 months ago

@drouleau-gtvr you should use CLAUDE_PROJECT_DIR and not depend on relative paths https://code.claude.com/docs/en/hooks#project-specific-hook-scripts.

github-actions[bot] · 7 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.