diagnose

install
source · Clone the upstream repo
git clone https://github.com/LilMGenius/win-hooks
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/LilMGenius/win-hooks "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/diagnose" ~/.claude/skills/lilmgenius-win-hooks-diagnose && rm -rf "$T"
manifest: skills/diagnose/SKILL.md
source content

Win-Hooks Diagnostics

Diagnose and fix Claude Code plugin hook compatibility issues on Windows.

Common Error Patterns

"JSON Parse error: Unrecognized token ''" / ":: command not found" / "#!/bin/bash: No such file or directory" / "<<(을)를 지정된 경로를 찾지 못했습니다"

Root cause: UTF-8 BOM (EF BB BF) in any hook file. In hooks.json it causes JSON parse errors; in

run-hook.cmd
it breaks bash's
:
builtin AND it pushes the leading
:
off line-start so cmd.exe stops recognizing it as a label and instead parses the polyglot's
<<
heredoc opener as redirection (mojibake:
<<��(��) ������� �ʾҽ��ϴ�
); in wrapper scripts it breaks shebang parsing. Typically caused by Windows editors or PowerShell
Out-File
. Fix: Run
/win-hooks:fix
verify --fix
strips BOM from every file in
hooks/
,
_hooks/
, and any file referenced from
hooks.json
(e.g.,
scripts/run-hook.cmd
shipped by ralph-loop).

"Hook load failed: JSON Parse error"

Root causes (check in order):

  1. UTF-8 BOM in hooks.json
  2. CRLF line endings causing parser issues
  3. Corrupted hooks.json from interrupted patching
  4. Invalid JSON syntax from bad text replacement

Fix: Run

/win-hooks:fix
which runs the full pipeline including
verify --fix
.

"SyntaxError" from python3/node on a .py/.js hook file

Root cause: Plugin ships bash wrapper scripts with

.py
/
.js
extension that call the interpreter on themselves (e.g.,
pretooluse.py
is
#!/bin/bash
but contains
python3 pretooluse.py
). Python/Node can't parse bash syntax. Fix: Run
/win-hooks:fix
verify --fix
disables recursive wrappers with
exit 0
.

"No such file or directory" for hook command

Root cause: Hook references a

.sh
script or bare command that doesn't exist on Windows. Fix: Run
/win-hooks:fix
to create polyglot wrappers.

"MODULE_NOT_FOUND" in Node.js hooks

Root cause: Windows backslash paths in

settings.json
hook commands get mangled during execution — backslashes are interpreted as escape characters, producing paths like
Userssmsme.configaincreport-usage.js
. Fix: Run
/win-hooks:fix
which converts
C:\...
to
C:/...
in settings.json hooks via
fix-backslash-paths
.

"'node' is not recognized as an internal or external command" / "'node'은(는) 내부 또는 외부 명령... 아닙니다" on Stop/SessionStart hooks

Root cause:

settings.json
hook command starts with a bare interpreter (
node
,
python
,
python3
,
npx
,
npm
) that's on Git Bash's PATH but not resolvable by cmd.exe at hook launch. Error text may appear CP949-garbled (e.g.
'node'��(��) ���� �Ǵ� �ܺ� ����...
). Note: the similar-looking
<<(을)를 지정된 경로를 찾지 못했습니다
(mojibake
<<��(��) ������� �ʾҽ��ϴ�
) is a different error — that one is BOM-corrupted polyglot wrapper (see the BOM section above). Fix: Run
/win-hooks:fix
fix-bare-commands
rewrites the command to a quoted absolute path like
"C:/Program Files/nodejs/node.exe" <script>
.

Why Hooks Break on Windows

Most Claude Code plugins are developed on Unix. Their hooks use:

  • .sh
    scripts called directly (cmd.exe cannot execute these)
  • Bare Unix commands not in Windows PATH (e.g.,
    semgrep
    ,
    shellcheck
    )
  • ${CLAUDE_PLUGIN_ROOT}
    path with
    .sh
    extension (triggers Claude Code's auto-detection)
  • Unix-specific shell syntax (
    $(...)
    , pipes, etc.)

Diagnosis Procedure

Step 1: Identify Platform

Check that platform is

win32
. If not, this skill does not apply.

Step 2: Find win-hooks install path

sed '1s/^\xEF\xBB\xBF//' ~/.claude/plugins/installed_plugins.json | awk '
  /win-hooks/ { found=1 }
  found && /"installPath"/ {
    sub(/.*"installPath"[[:space:]]*:[[:space:]]*"/, "")
    sub(/".*/, "")
    print
    exit
  }
' | sed 's/[\\][\\]*/\//g'

Save the output path as PLUGIN_ROOT.

Step 3: Run health check

bash "<PLUGIN_ROOT>/scripts/verify"

This detects:

Issue TypeMeaning
bomUTF-8 BOM in any hook file (hooks/, _hooks/, or any file referenced from hooks.json)
json_invalidhooks.json is not valid JSON
json_crlfCRLF line endings in hooks.json
wrapper_missingPatched hook references nonexistent wrapper script
cmd_missing_hooks/run-hook.cmd is missing
recursive_wrapperBash wrapper (.py/.js) calls python3/node on itself
backslash_pathsettings.json hook command has Windows backslash paths
bare_commandsettings.json hook command uses bare interpreter not resolvable by cmd.exe

Step 4: Run incompatibility scanner

bash "<PLUGIN_ROOT>/scripts/find-incompatible"

Step 5: Report Findings

Present a table:

| Plugin | Issue | Detail | Status |
|--------|-------|--------|--------|
| name   | type  | info   | OK/FIX |

Fix Procedure

Automatic (recommended)

bash "<PLUGIN_ROOT>/hooks/patch-all"

This runs the full pipeline:

  1. find-incompatible
    → detects incompatible hooks
  2. apply-patches
    → creates wrappers, patches hooks.json (sanitizes BOM/CRLF, validates JSON)
  3. verify --fix
    → auto-repairs any remaining encoding issues

Manual repair for specific files

For BOM/CRLF issues only:

bash "<PLUGIN_ROOT>/scripts/verify" --fix

For restoring a broken hooks.json from backup:

cp <plugin>/hooks/hooks.json.bak <plugin>/hooks/hooks.json

Then re-run patch-all.

Hook Event Types

Any of these can have incompatible commands:

CategoryEvents
SessionSessionStart, SessionEnd, InstructionsLoaded
User InputUserPromptSubmit
ToolsPreToolUse, PostToolUse, PostToolUseFailure, PermissionRequest
AgentsSubagentStart, SubagentStop, Stop, TeammateIdle, TaskCompleted
ContextPreCompact, PostCompact, ConfigChange
IntegrationNotification, Elicitation, ElicitationResult
WorktreeWorktreeCreate, WorktreeRemove

Automatic Prevention

The win-hooks plugin runs its patcher at every SessionStart. If you install or update a plugin, simply restart Claude Code - the patcher will detect and fix new incompatibilities automatically.

Rollback

# Restore a plugin's original hooks.json
cp <plugin>/hooks/hooks.json.bak <plugin>/hooks/hooks.json

Troubleshooting

Hook still errors after patching:

  • Check if Git Bash is installed at
    C:\Program Files\Git\bin\bash.exe
  • Verify the wrapper script has correct content:
    cat <plugin>/_hooks/<wrapper-name>
  • Run with debug:
    claude --debug hooks
    to see hook execution details

python3 not found (other plugins):

  • win-hooks automatically copies
    python.exe
    python3.exe
    if
    python3
    is missing
  • If Python is not installed at all, plugins that require Python will still fail

Plugin update overwrites fix:

  • This is expected. Restart Claude Code and win-hooks will re-patch automatically.