Skip to content

gstack-hook-check reports every TypeScript hook as "bun could not bundle" on Windows (Git Bash): MSYS argv path conversion breaks the built.tsv lookup #3100

Closed

Description

@bkermen

Summary

On Windows with Git Bash, ./setup (v1.91.66.0+) exits 1 and refuses to register every TypeScript-backed
hook, with bun could not bundle the TypeScript entry. The hooks bundle fine. The failure is in
bin/gstack-hook-check's bookkeeping:

  • It passes absolute POSIX paths (/c/Users/...) to bun.exe as argv.
  • MSYS converts native-exe argv to Windows form (C:/Users/...).
  • Bun.build therefore records rows keyed C:/Users/... in built.tsv.
  • The later lookup searches for /c/Users/..., finds nothing, and treats a missing row as a bundle
    failure.

gstack-doctor shows the same false hooks: fail.

Environment

  • gstack 1.91.68.0 (20eb620), global Claude install at ~/.claude/skills/gstack
  • Windows 11 Pro, Git for Windows (Git Bash / MSYS2 runtime)
  • Bun 1.4.2

Symptoms

./setup ends with exit 1:

gstack setup: refusing to register hooks that do not parse (Claude Code would block tool calls with them):
  .../hosts/claude/hooks/question-log-hook.ts:1: bun could not bundle the TypeScript entry
  .../hosts/claude/hooks/question-preference-hook.ts:1: bun could not bundle the TypeScript entry
  .../hosts/claude/hooks/auq-error-fallback-hook.ts:1: bun could not bundle the TypeScript entry
  .../hosts/claude/hooks/timeline-stop-hook.ts:1: bun could not bundle the TypeScript entry
  .../autoplan/bin/phase-publication-hook.ts:1: bun could not bundle the TypeScript entry
  .../plan-ceo-review/bin/mode-handoff-hook.ts:1: bun could not bundle the TypeScript entry
  Hooks that parse register as usual: bin/gstack-session-update careful/bin/check-careful.sh freeze/bin/check-freeze.sh

bin/gstack-doctor then reports fail hooks ... bun could not bundle the TypeScript entry.

The hooks are fine

The same entries bundle without error:

cd ~/.claude/skills/gstack/hosts/claude/hooks
bun build ./timeline-stop-hook.ts --target=bun --outdir "$(mktemp -d)"
# Bundled 4 modules in 11ms   (exit 0)

The check's own Bun.build call also succeeds. It is the argv spelling that changes:

E="$HOME/.claude/skills/gstack/hosts/claude/hooks/timeline-stop-hook.ts"   # /c/Users/.../timeline-stop-hook.ts
bun -e 'for (const e of process.argv.slice(1)) { const r = await Bun.build({ entrypoints: [e], target: "bun", packages: "external", metafile: true, throw: false }); console.log(`argv=${e} success=${r.success} inputs=${Object.keys(r.metafile?.inputs ?? {}).length}`) }' "$E"
# argv=C:/Users/.../timeline-stop-hook.ts success=true inputs=4

MSYS_NO_PATHCONV=1 bun -e 'console.log(process.argv[1])' "$E"
# /c/Users/.../timeline-stop-hook.ts

Root cause (bin/gstack-hook-check at 1.91.68.0)

  1. Line 55 normalizes ROOT to POSIX form on Windows: ROOT=$(cygpath -u "$ROOT"), giving /c/Users/....
  2. Lines 148-153 build ENTRIES as absolute paths under that POSIX ROOT:
    ENTRIES="$ENTRIES${shim%/*}/$entry$NL".
  3. Line 156 onward runs "$BUN" -e '...' $ENTRIES > "$BUILT". bun.exe is a native Windows
    executable, so the MSYS runtime rewrites each /c/... argument to C:/.... The script prints
    ${entry}, the rewritten spelling, as column 1 of built.tsv.
  4. Line 206 looks rows up by the POSIX spelling:
    result=$(awk -F '\t' -v e="$dir/$entry" '$1 == e' "$BUILT"). No row matches, so result is empty.
  5. An empty result is reported as bun could not bundle the TypeScript entry (line ~208), even though
    the build succeeded.

So on Git Bash every TypeScript hook is rejected, whatever its content.

Suggested fixes (any one)

  • Pass entries relative to ROOT. The script already does cd "$ROOT" before invoking bun, and MSYS
    does not rewrite relative paths. Key both the TSV and the lookup by the relative path.
  • Normalize the lookup key on Windows: compare against cygpath -m "$dir/$entry" (or normalize both
    sides) in the awk lookup.
  • Have the bun script echo the caller's spelling: pass entries via stdin or an env var (not
    converted by MSYS) instead of argv, and print exactly what it received.
  • Distinguish "no row" from "build failed" in the message, e.g. no build result recorded for <entry>, so a bookkeeping miss isn't reported as a bundle error.

Impact

  • ./setup exits 1 on every Windows Git Bash install from 1.91.66.0 onward, and gstack-doctor
    reports hooks: fail.
  • Settings-level TypeScript hooks are not (re)registered. Previously registered fail-open hooks (the
    timeline-stop-hook Stop shim) keep working. Skill-frontmatter hooks that call their scripts by path
    (/autoplan, /plan-ceo-review) also keep working, since the scripts exist and build.
  • Users following the message's advice ("repair the file ... half-applied edits") will find nothing
    to repair.

Activity

  1. gfl130902-maker commented on Oct 11, 2026

    @gfl130902-maker

    Still reproduces on 1.91.83.0 (5cb5e1c) — Windows 11 10.0.26300, Git Bash, Bun 1.4.3. All six TS-entry hooks were skipped on a fresh install.

    Confirmed locally that accepting both spellings in the lookup fixes it (gstack-hook-check then reports 9/9 ok and setup registers every hook):

    -    result=$(awk -F '\t' -v e="$dir/$entry" '$1 == e' "$BUILT")
    +    wkey="$dir/$entry"
    +    command -v cygpath >/dev/null 2>&1 && wkey=$(cygpath -m "$dir/$entry")
    +    result=$(awk -F '\t' -v e="$dir/$entry" -v w="$wkey" '$1 == e || $1 == w' "$BUILT")

    Note MSYS2_ARG_CONV_EXCL='*' is not a workaround: bun then fails with EINVAL: failed to open root directory: /c/Users/....

  2. capy-ai commented on Oct 11, 2026

    @capy-ai
    Contributor

    Fixed in v1.91.89.0 (e6edff0, #3140). This is the same false positive as #3088: Bun reported C:/ paths while the checker looked up /c/. The fix adopts @yuriysan's #3112.

    To recover a stuck install, run this once from Git Bash:

    cd ~/.claude/skills/gstack && git pull --ff-only --autostash && ./setup
    

    It also clears /gstack-upgrade's "is not a gstack checkout" refusal. Thanks @bkermen. You're credited as co-author on the merged commit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions