mirror of
https://github.com/obra/superpowers.git
synced 2026-09-25 22:09:05 +00:00
SessionStart hook produces no output on Windows (Git Bash shebang issue) #354
Labels
No labels
antigravity
automated-issue-report
brainstorming
bug
claude-code
codex
copilot
cursor
documentation
duplicate
enhancement
factory
gemini-cli
good first issue
help wanted
hermes
hooks
invalid
kiro
needs-categorization
needs-rebase-to-dev-branch
needs-repro-case
new-harness
no-obvious-human-review
opencode
pi
plans
pr-template-rules-ignored
question
skill:brainstorming
skill:diagnosing-superpowers
skill:dispatching-parallel-agents
skill:executing-plans
skill:finishing-a-development-branch
skill:receiving-code-review
skill:requesting-code-review
skills
skill:subagent-driven-development
skill:systematic-debugging
skill:test-driven-development
skill:using-git-worktrees
skill:using-superpowers
skill:verification-before-completion
skill:writing-plans
skill:writing-skills
stale
subagents
tdd
trae
triage
upstream-bug
windows
wontfix
worktrees
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
skills/obra-superpowers#354
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Description
The
session-start.shhook fails to produce any output when executed on Windows with Git Bash, causing the "SessionStart:startup hook error" message to appear at startup.Environment
Problem
When Claude Code runs the SessionStart hook on Windows, it executes:
The script has a shebang line
#!/usr/bin/env bash, and when executed this way on Windows/Git Bash, no stdout is produced even though the script exits with code 0.Investigation Results
I tested extensively and found:
bash script.sh(with shebang)source script.shbash script.sh(without shebang)This appears to be a quirk of how Git Bash on Windows handles scripts with shebang lines when invoked as
bash script.sh.Debug Log Evidence
From Claude Code debug log:
The hook runs but produces empty/non-JSON output, triggering the error display.
Suggested Fixes
Option 1: Remove the shebang line
Since Claude Code 2.1.x already prepends
bashwhen running.shfiles on Windows, the shebang is redundant and causes the issue.Option 2: Use a wrapper approach
Have the hook command use
bash -c 'source ...'instead of directly invoking the script.Option 3: Add Windows-specific detection
Check for Windows in hooks.json and use a different command format.
Additional Context
The existing
run-hook.cmdpolyglot wrapper was deprecated per its comments because Claude Code 2.1.x changed the execution model. However, the new model still has issues with shebang handling on Windows.+1
+1
Root Cause Analysis
I investigated this issue in depth and found two distinct problems causing the SessionStart hook to fail on Windows:
Problem 1: Path Mangling (Primary Cause of "No such file or directory")
When Claude Code executes the hook, it sets
CLAUDE_PLUGIN_ROOTto a Windows path with backslashes (e.g.,C:\Users\Sebastian\.claude\plugins\...). When this is passed through bash command execution, the backslashes are interpreted as escape characters and stripped:The path becomes
C:UsersSebastian...instead ofC:\Users\Sebastian\....Problem 2: Shebang stdout suppression (Secondary Issue)
Even when the path is correct, Git Bash on Windows suppresses stdout when running scripts with shebang lines via
bash script.sh:This appears to be a quirk of how Git Bash handles the
#!/usr/bin/env bashshebang when the script is invoked asbash script.sh.Fix
I've submitted #356 which replaces the bash script with a cross-platform Node.js equivalent that:
__dirnamefor reliable path resolution (avoiding the CLAUDE_PLUGIN_ROOT backslash issue)This follows the same pattern used by other plugins (like
everything-claude-code) that work correctly on Windows.Root Cause Analysis
I investigated this issue in depth and found two distinct problems causing the SessionStart hook to fail on Windows:
Problem 1: Path Mangling (Primary Cause of "No such file or directory")
When Claude Code executes the hook, it sets
CLAUDE_PLUGIN_ROOTto a Windows path with backslashes (e.g.,C:\Users\Sebastian\.claude\plugins\...). When this is passed through bash command execution, the backslashes are interpreted as escape characters and stripped:The path becomes
C:UsersSebastian...instead ofC:\Users\Sebastian\....Problem 2: Shebang stdout suppression (Secondary Issue)
Even when the path is correct, Git Bash on Windows suppresses stdout when running scripts with shebang lines via
bash script.sh:This appears to be a quirk of how Git Bash handles the
#!/usr/bin/env bashshebang when the script is invoked asbash script.sh.Fix
I've submitted #356 which replaces the bash script with a cross-platform Node.js equivalent that:
__dirnamefor reliable path resolution (avoiding the CLAUDE_PLUGIN_ROOT backslash issue)This follows the same pattern used by other plugins (like
everything-claude-code) that work correctly on Windows.Node isn't guaranteed to be installed anymore, but bash is, so a node script, sadly, isn't a plausible solution.
Node isn't guaranteed to be installed anymore, but bash is, so a node script, sadly, isn't a plausible solution.
Partial fix update
Two of the three Windows SessionStart problems have been fixed on main:
async: true(961052e): Hook failures no longer freeze the terminalescape_for_json(038abed): ~7x faster, eliminates performance-related timeoutsThe path mangling problem described in the root cause analysis comment (CLAUDE_PLUGIN_ROOT backslash stripping) is tracked at #420 (canonical issue, upstream at anthropics/claude-code#23204).
Still open here: The Git Bash shebang stdout suppression (
bash script.shwith shebang → no output) is a distinct issue not addressed by the above fixes. Keeping this open to track that.Investigation: shebang + onecmd interaction
We investigated the shebang stdout suppression in depth. The root cause is Claude Code's
onecmd(-t) bash option (anthropics/claude-code#19217).When CC runs
bash session-start.shwith-tactive, bash reads the shebang line (#\!/usr/bin/env bash) and counts it as the "one command" — then exits before executing any script body. This is why removing the shebang fixes it: without it,set -euo pipefailbecomes the one command that runs, and the rest is lost too, but differently.We tested
set +tas a workaround, but it does not work when a shebang is present — the shebang consumes the one-command slot beforeset +tever executes:bash -tresultset +t+ echoset +tas first lineConclusion: This is not fixable from the plugin side without removing the shebang (which would break macOS/Linux) or adding a janky wrapper layer. This is an upstream CC bug — CC should not set
onecmdwhen executing hook scripts.The
async: truefix (961052e) means the terminal won't freeze, but the hook still produces no output on affected Windows systems, so skills don't load.