PostToolUse hooks for Edit/Write never fire (v2.1.47)

Resolved 💬 2 comments Opened Feb 19, 2026 by mjientara Closed Mar 20, 2026

Bug Description

PostToolUse hooks configured for Edit and Write tools never execute. The hook command is never invoked — confirmed via debug logging (log file is never created). SessionStart hooks in the same config file fire correctly.

Environment

  • Claude Code version: 2.1.47
  • OS: macOS (Darwin 25.3.0)
  • Shell: zsh
  • jq: 1.7.1-apple (installed)

Configuration

~/.claude/settings.json (relevant excerpt):

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit",
        "hooks": [{ "type": "command", "command": "/Users/me/.claude/auto-commit.sh" }]
      },
      {
        "matcher": "Write",
        "hooks": [{ "type": "command", "command": "/Users/me/.claude/auto-commit.sh" }]
      }
    ],
    "SessionStart": [
      {
        "hooks": [{ "type": "command", "command": "node /Users/me/.claude/hooks/gsd-check-update.js" }]
      }
    ]
  },
  "permissions": {
    "defaultMode": "acceptEdits"
  }
}

auto-commit.sh — reads tool_input.file_path from stdin JSON, resolves git root, runs git add -A. Script is executable (chmod +x), works perfectly when run manually.

Reproduction Steps

  1. Configure PostToolUse hooks for Edit and Write as shown above
  2. Start a new Claude Code session inside a git repository
  3. Ask Claude to edit or create a file (triggering Edit or Write tool)
  4. Check git status --porcelain — file appears as ?? (untracked) or M (unstaged), never A (staged)

Test Matrix

| # | Test | Permission Mode | CWD | Project Settings | Hook Fired? |
|---|------|----------------|-----|-----------------|-------------|
| 1 | Write new file | acceptEdits | inside repo | yes (with own PostToolUse) | NO |
| 2 | Edit tracked file | acceptEdits | inside repo | yes | NO |
| 3 | Write new file | acceptEdits | inside repo | none (dotfiles) | NO |
| 4 | Edit with debug log | acceptEdits | inside repo | none | NO (log file never created) |
| 5 | Write with debug log | acceptEdits | inside repo | none | NO (log file never created) |
| 6 | Edit with 3s delay | acceptEdits | inside repo | yes | NO |
| 7 | Write new file | default | ~ (not a repo) | n/a | NO |
| 8 | Write new file | default | test inside ~/dotfiles | none | NO |
| 9 | Manual script execution | n/a | inside repo | n/a | YES (stages correctly) |

Key Observations

  • SessionStart hooks fire correctly — the hook system loads and executes
  • PreToolUse hooks for Bash matchers appear to work (e.g., Bash(git commit:*))
  • PostToolUse hooks for Edit/Write specifically never fire — the command is never invoked
  • Debug logging confirms non-execution — a script that writes to /tmp/hook-debug.log as its first line produces no log file
  • Not a permission mode issue — fails with both acceptEdits and default
  • Not a CWD issue — fails inside and outside git repos
  • Not a project settings override issue — fails with and without project-level .claude/settings.json
  • The script itself works — manual execution with the expected JSON input stages files correctly

Expected Behavior

After Edit or Write tool completes, the PostToolUse hook command should execute with the tool input/output JSON on stdin.

Actual Behavior

The hook command is never executed. No side effects, no log output, no errors.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗