Skip to content

Latest commit

 

History

History
168 lines (120 loc) · 4.71 KB

File metadata and controls

168 lines (120 loc) · 4.71 KB
name claude-windows-hook-fix
description Fix for Claude Code v2.1.x hooks not working on Windows. Patches cli.js to properly invoke bash as a login shell, enabling MSYS path translation. Use when Windows hooks fail with "No such file or directory" errors.
version 1.0.0
author Zac Cook
platforms windows
claude-code-versions 2.1.x

Claude Code Windows Hook Fix

Problem Summary

Claude Code v2.1.x on Windows has a critical bug where all hooks fail with errors like:

/bin/bash: /c/hooks/stop.sh: No such file or directory

This occurs even when the files exist and are accessible. The bug affects ALL hook types:

  • SessionStart
  • UserPromptSubmit
  • PreToolUse
  • PostToolUse
  • Stop
  • PreCompact

Root Cause

Claude Code executes hooks using Node.js spawn with shell: true:

hB7(V, [], {env:F, cwd:j1(), shell:!0})

On Windows, Claude Code sets process.env.SHELL to the Git Bash path. When shell: true is used, Node.js invokes bash, but without the MSYS/MinGW environment that provides path translation (/c/ → C:\).

The bash process runs in a "bare" mode without:

  • MSYS path translation
  • Proper $HOME (points to /home/user instead of /c/Users/user)
  • MinGW environment variables

The Fix

One-Line Patch

Run this command to patch Claude Code:

sed -i 's/hB7(V,\[\],{env:F,cwd:j1(),shell:!0})/hB7(process.env.SHELL||"bash",["-l","-c",V],{env:F,cwd:j1(),shell:!1})/g' "$(npm root -g)/@anthropic-ai/claude-code/cli.js"

What It Changes

Before:

hB7(V, [], {env:F, cwd:j1(), shell:!0})

After:

hB7(process.env.SHELL||"bash", ["-l","-c",V], {env:F, cwd:j1(), shell:!1})

Why It Works

  1. process.env.SHELL||"bash" - Uses bash path directly as the executable
  2. ["-l", "-c", V] - Key flags:
    • -l = Login shell (loads full MSYS environment including path translation)
    • -c = Command mode
    • V = The hook command string
  3. shell:!1 (shell: false) - Spawns bash directly, avoiding double-shell issues

The -l flag is critical - it makes bash initialize as a login shell, which loads /etc/profile and user profile scripts that set up the MSYS environment.

Installation

Automatic (Recommended)

# Backup original
cp "$(npm root -g)/@anthropic-ai/claude-code/cli.js" "$(npm root -g)/@anthropic-ai/claude-code/cli.js.backup"

# Apply patch
sed -i 's/hB7(V,\[\],{env:F,cwd:j1(),shell:!0})/hB7(process.env.SHELL||"bash",["-l","-c",V],{env:F,cwd:j1(),shell:!1})/g' "$(npm root -g)/@anthropic-ai/claude-code/cli.js"

Verify Patch

grep -o 'process.env.SHELL.*\-l.*\-c' "$(npm root -g)/@anthropic-ai/claude-code/cli.js"

Should output something containing: process.env.SHELL||"bash",["-l","-c"

Restore Original (If Needed)

cp "$(npm root -g)/@anthropic-ai/claude-code/cli.js.backup" "$(npm root -g)/@anthropic-ai/claude-code/cli.js"

Important Notes

Patch Persistence

⚠️ This patch is overwritten when Claude Code updates.

After any Claude Code update, re-run the patch command.

Consider creating a post-install script or alias:

alias claude-fix='sed -i '\''s/hB7(V,\[\],{env:F,cwd:j1(),shell:!0})/hB7(process.env.SHELL||"bash",["-l","-c",V],{env:F,cwd:j1(),shell:!1})/g'\'' "$(npm root -g)/@anthropic-ai/claude-code/cli.js"'

Hook Path Format

With the patch applied, use Unix-style paths in your hooks:

{
  "hooks": {
    "Stop": [{
      "hooks": [{
        "type": "command",
        "command": "/c/hooks/stop.sh"
      }]
    }]
  }
}

Affected Versions

  • Confirmed affected: Claude Code v2.1.9, v2.1.11
  • Likely affected: All v2.1.x versions on Windows
  • Platform: Windows with Git Bash

Related Issues

Testing

After applying the patch:

  1. Close all terminals
  2. Open a fresh terminal
  3. Run claude
  4. Verify no hook errors appear
  5. Test hooks execute correctly

Technical Details

File Location

Windows: %APPDATA%\npm\node_modules\@anthropic-ai\claude-code\cli.js
Unix path: C:/Users/<user>/AppData/Roaming/npm/node_modules/@anthropic-ai/claude-code/cli.js

Code Context

The patched code is in the hook execution function. The original code at approximately line 63 (in minified form) handles spawning hook commands. The hB7 function is a wrapper around Node.js spawn.

Environment Variables

Claude Code sets these on Windows:

  • SHELL → Path to Git Bash (e.g., C:\Program Files\Git\bin\bash.exe)
  • CLAUDECODE=1
  • CLAUDE_CODE_SSE_PORT → SSE communication port

The fix ensures bash receives these AND initializes its own MSYS environment via the login shell flag.