Skip to content

Windows: bun run build fails with command not found: { — bash brace groups in package.json scripts.build #1457

@sarabvaruna-code

Description

@sarabvaruna-code

Summary

On Windows (Git Bash + Bun's built-in script runner), bun run build fails after compiling all binaries because package.json line 12's scripts.build contains three bash brace groups { cmd; } which Bun's Windows shell parser doesn't support. The compile steps succeed but the .version-write step throws three bun: command not found: { errors and exits with code 1.

Knock-on impact: when setup invokes bun run build and the build exits non-zero, the subshell-wrapped call masks the failure (outer setup exit code stays 0) but the script DOES bail out of the build subshell, so the downstream link_claude_skill_dirs step is never reached. Result: stale top-level skill registrations on Windows (filed separately).

Steps to Reproduce

Minimal isolation — no gstack needed:

mkdir -p /tmp/bun-brace-test && cd /tmp/bun-brace-test
cat > package.json <<'PKG'
{
  "name": "brace-test",
  "scripts": {
    "test-parens": "( echo hello-parens )",
    "test-braces": "{ echo hello-braces; }",
    "test-version-pattern": "{ git rev-parse HEAD 2>/dev/null || true; } > /tmp/version-out.txt"
  }
}
PKG

bun run test-parens
# $ ( echo hello-parens )
# hello-parens                           <-- works

bun run test-braces
# $ { echo hello-braces; }
# bun: command not found: {
# bun: command not found: }
# error: script "test-braces" exited with code 1

bun run test-version-pattern
# Same error pattern.

Full gstack repro:

cd ~/.claude/skills/gstack && bun run build 2>&1 | tail -10
# (after the compiles succeed:)
# bun: command not found: {
# bun: command not found: }
# bun: command not found: }
# error: script "build" exited with code 1

Expected Behavior

bun run build exits 0 on Windows after successfully writing all three .version files.

Actual Behavior

Bun's Windows shell parser interprets { and } as command names, not as brace-group syntax. The compile steps complete, then the three .version-write steps fail back-to-back, and the entire bun run build exits with code 1.

The existing safety net at setup lines 242-245 catches the missing browse/dist/.version after the failure, but the two sibling .version files (design/dist/.version, make-pdf/dist/.version) get no such fallback, and the non-zero exit code is what trips the silent setup bail-out.

Root Cause

package.json line 12, three occurrences of bash brace groups:

... && { git rev-parse HEAD 2>/dev/null || true; } > browse/dist/.version
    && { git rev-parse HEAD 2>/dev/null || true; } > design/dist/.version
    && { git rev-parse HEAD 2>/dev/null || true; } > make-pdf/dist/.version && ...

POSIX bash treats { cmd; } as a brace group (no subshell, same environment). Bun's Windows shell parser does NOT implement brace-group parsing. The runner falls through to treating { as a literal command-to-invoke.

Suggested Patch

Replace each brace group with a parenthesis subshell. Functionally equivalent for one-shot stdout redirection (no shared-variable semantics needed here):

-    "build": "... && { git rev-parse HEAD 2>/dev/null || true; } > browse/dist/.version && { git rev-parse HEAD 2>/dev/null || true; } > design/dist/.version && { git rev-parse HEAD 2>/dev/null || true; } > make-pdf/dist/.version && ...",
+    "build": "... && ( git rev-parse HEAD 2>/dev/null || true ) > browse/dist/.version && ( git rev-parse HEAD 2>/dev/null || true ) > design/dist/.version && ( git rev-parse HEAD 2>/dev/null || true ) > make-pdf/dist/.version && ...",

Subshells ( ... ) are universally supported in POSIX bash, zsh, and Bun's Windows shell. The cost (spawning a subshell vs sharing env) is irrelevant for a one-line git rev-parse + redirect.

Workaround (for users on current setup)

Either:

  1. Local patch of package.json line 12 (will conflict on next git pull).
  2. Skip the build step entirely if binaries are already current — touch ~/.claude/skills/gstack/browse/dist/browse (and the other 4 binaries) to push their mtime past package.json and bun.lock. Setup's NEEDS_BUILD=0 check at line 224 then skips the build call.

Environment

  • Windows 11 Home 10.0.26200
  • Git Bash (MINGW64)
  • bun 1.3.13
  • gstack v1.33.2.0 (HEAD dc6252d1)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions