Stop hook fails with 'spawn /bin/sh ENOENT' on every session end (v2.1.39)

Resolved 💬 3 comments Opened Feb 22, 2026 by KlementMultiverse Closed Feb 26, 2026

Bug Description

The Stop hook consistently fails with the following error on every session end:

Stop hook error: Failed with non-blocking status code: Error occurred while executing hook command: spawn /bin/sh ENOENT

Environment

  • Claude Code version: 2.1.39
  • OS: Ubuntu 22.04 (Linux)
  • Shell: /bin/sh → dash (verified to exist and work)

Hook Configuration

"Stop": [
  {
    "hooks": [
      {
        "type": "command",
        "command": "python3 /home/user/.nathan/scripts/stop.py",
        "timeout": 10
      }
    ]
  }
]

What I've Verified

  • /bin/sh exists and works: ls -la /bin/shlrwxrwxrwx /bin/sh -> dash
  • /bin/sh -c "echo test" works correctly from a terminal
  • The hook script itself runs correctly when invoked directly: echo '{}' | python3 stop.py exits 0
  • All other hooks (UserPromptSubmit, PreToolUse, PostToolUse, PreCompact) work correctly
  • The error only occurs on the Stop hook

Root Cause Hypothesis

Node.js spawn('/bin/sh', ['-c', 'command']) fails with ENOENT when the Stop hook fires during Claude Code process teardown. It appears that by the time the Stop hook runs, the Node.js runtime's ability to spawn child processes is already partially torn down — even though /bin/sh exists on the filesystem and works in normal execution.

This is a known pattern: shutdown hooks in Node.js sometimes can't access system resources that were available during normal operation.

Impact

  • The hook is marked "non-blocking" so Claude Code continues normally
  • However, session finalization actions (writing daily logs, merging state) do not run
  • This affects every single session end — it is 100% reproducible

Workaround

None found. The only viable workaround is to move stop-hook logic to PreCompact instead, which runs reliably.

Request

Please ensure the Stop hook's command is spawned before the Node.js process begins teardown, or document that Stop hooks cannot reliably spawn child processes.

View original on GitHub ↗

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