Stop hook fails with ENOENT when project directory has been deleted
Summary
When a Claude Code session's working directory is deleted during the session, the Stop hook fails with a non-blocking error:
Stop hook error: Failed with non-blocking status code: Error occurred while
executing hook command: ENOENT: no such file or directory, posix_spawn '/bin/sh'
Steps to Reproduce
- Open a Claude Code session in a project directory (e.g.
~/Developer/my-project) - During the session, delete the working directory (e.g. via
rm -rf ~/Developer/my-project) - End the session — the Stop hook fires and fails with ENOENT
Root Cause
Claude Code spawns the hook shell process with cwd set to the project directory. When that directory no longer exists, Node.js's child_process.spawn throws ENOENT before the shell process can start — even though the shell binary itself (/bin/sh) exists. There is no way to work around this from within the hook command itself.
Expected Behavior
Stop hooks should fall back to $HOME (or /tmp) as the working directory when the original project directory no longer exists.
Actual Behavior
The hook fails with ENOENT: no such file or directory, posix_spawn '/bin/sh' because Node.js cannot spawn the shell with a non-existent cwd.
Workaround
Adding "async": true to the Stop hook suppresses the visible error, but the hook still does not execute.
Additional Context
- The hook schema does not expose a
cwdfield to let users override the working directory per-hook. - Platform: macOS (darwin 25.3.0)
- Suggested fix: if the hook's cwd does not exist at fire time, fall back to the user's home directory.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗