Windows: SessionStart hooks with .sh scripts fail due to path handling

Resolved 💬 4 comments Opened Feb 5, 2026 by cmwalton Closed Feb 8, 2026

Description

On Windows, SessionStart hooks that execute .sh scripts consistently fail with a path parsing error. The error appears as:

SessionStart:startup hook error

This affects any plugin that uses shell script hooks on Windows, including the superpowers plugin.

Environment

  • Claude Code version: 2.1.31
  • OS: Windows 11
  • Shell: PowerShell / Windows Terminal
  • Bash available: Yes (Git Bash at C:\Program Files\Git\usr\bin\bash.exe)

Steps to Reproduce

  1. Install the superpowers plugin (or any plugin with a SessionStart .sh hook)
  2. Start a new Claude Code session on Windows
  3. Observe the "SessionStart:startup hook error" message

Investigation Details

The superpowers plugin defines a SessionStart hook in hooks/hooks.json:

{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "startup|resume|clear|compact",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PLUGIN_ROOT}/hooks/session-start.sh"
          }
        ]
      }
    ]
  }
}

Key findings:

  1. Script works when run directly:

``
bash "C:/Users/username/.claude/plugins/cache/.../session-start.sh"
``
This executes successfully and produces valid JSON output.

  1. Script fails when invoked through cmd.exe:

``
cmd /c "bash 'C:/Users/username/.claude/plugins/cache/.../session-start.sh'"
`
Error:
'chloe' is not recognized as an internal or external command`

The error output shows wide character spacing, suggesting an encoding issue in path handling.

  1. Bash is correctly in PATH:

``
where bash
C:\Program Files\Git\usr\bin\bash.exe
``

Expected Behavior

SessionStart hooks with .sh scripts should execute successfully on Windows, as documented in the 2.1.x release notes regarding auto-detection of .sh files.

Actual Behavior

The hook fails every time a session starts. The path appears to be corrupted or incorrectly quoted before being passed to bash.

Workaround

Currently, the only workaround is to disable plugins that use .sh hooks.

Additional Context

The superpowers plugin includes a run-hook.cmd polyglot wrapper that was previously used for cross-platform compatibility. The comments in that file note that Claude Code 2.1.x changed the execution model, which may be related to this regression.

View original on GitHub ↗

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