Stop hook does not fire reliably in VSCode extension (works via CLI, confirmed via git history)

Open 💬 1 comment Opened Jul 14, 2026 by robingriffin-dev

Summary

The Stop hook does not reliably fire when Claude Code runs as the VSCode extension, even though it is correctly configured, executable, and works when the same command is run manually. SessionStart and PreToolUse hooks configured in the same file appear unaffected.

Environment

  • Claude Code VSCode extension: anthropic.claude-code-2.1.209-linux-x64
  • VSCode: 1.128.0 (commit fc3def6774c76082adf699d366f31a557ce5573f), linux x64
  • OS: Rocky Linux 9.8 (Blue Onyx), kernel 5.14.0-687.15.1.el9_8.x86_64
  • Remote/SSH-connected VSCode session (not local)

Hook configuration (~/.claude/settings.local.json)

{
  "SessionStart": [
    { "hooks": [ { "type": "command", "command": "/path/to/mem-pull.sh" } ] }
  ],
  "Stop": [
    { "hooks": [ { "type": "command", "command": "/path/to/mem-push.sh" } ] }
  ],
  "PreToolUse": [
    { "matcher": "Bash", "hooks": [ { "type": "command", "command": "/path/to/auto-approve-readonly.py" } ] }
  ]
}

mem-push.sh commits and pushes any pending changes in a git-tracked "memory" directory; it no-ops instantly if the working tree is clean. It is a plain bash script with a fast clean-tree exit path, so it should return near-instantly every time it's invoked.

Expected behavior

mem-push.sh runs at the end of every turn (per the hooks documentation, Stop is a standard per-turn event), committing and pushing any memory changes made during that turn.

Actual behavior

Across a session with several completed turns that modified files inside the hooked directory, the working tree remained dirty (git status --porcelain non-empty) after every turn. Running the exact same script manually (bash mem-push.sh) immediately committed and pushed with no errors — confirming the script itself works correctly and the problem is that the Stop event is not invoking it.

Evidence this is a regression, not a config mistake

Git history of the target repo shows the same hook firing reliably (commits named memory: <hostname> <timestamp>, generated only by this hook) dozens of times across multiple machines through 2026-07-09T21:07:12Z, then zero automatic commits for the next ~5 days, spanning multiple separate Claude Code sessions on the same machine, until a manual run on 2026-07-14T12:43:51Z produced an immediate commit+push. So the hook previously worked correctly and stopped firing at some point, without any corresponding change to the hook configuration itself (a settings restructure — splitting hooks into a per-machine settings.local.json from a shared settings.json — happened earlier the same day the auto-commits stopped, but auto-commits continued to fire correctly for several hours after that change, so it does not look like the direct cause).

Steps to reproduce

  1. Configure a Stop hook in settings.local.json that touches a git repo (e.g., commits any pending changes).
  2. Run a Claude Code session in the VSCode extension (SSH remote) that completes multiple turns modifying tracked files.
  3. Check the target repo's git status after each turn completes.
  4. Observe the working tree stays dirty; manually invoking the hook's command succeeds immediately.

Impact

Any workflow relying on Stop for end-of-turn side effects (this case: cross-machine memory sync via git) silently stops working, with no error surfaced to the user — the only symptom is state slowly falling out of sync until someone manually notices and intervenes.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗