Skip to content

[Bug]: pnpm build fails on Windows — WSL bash invoked by pnpm cannot find node (scripts/bundle-a2ui.sh) #26065

@BinHPdev

Description

@BinHPdev

Summary

Running pnpm build on Windows fails immediately at the canvas:a2ui:bundle step because pnpm resolves bash to WSL's bash (C:\Windows\System32\bash.exe) rather than Git Bash, and WSL does not have Node.js installed natively — causing every node-dependent call inside scripts/bundle-a2ui.sh to fail.

Steps to reproduce

Prerequisites:

  • Windows 11 with WSL2 installed (WSL's bash.exe is present in System32)
  • Git Bash installed, Node.js 22+ on the Windows side (accessible in Git Bash)
  • Node.js NOT installed inside WSL
  • pnpm 10 installed globally

Steps:

  1. Clone the repository on Windows.
  2. Run pnpm install from Windows cmd or PowerShell.
  3. Run pnpm build from Windows cmd or PowerShell.
  4. Observe the failure at the canvas:a2ui:bundle step.

Expected behavior

pnpm build completes successfully, or scripts/bundle-a2ui.sh detects the WSL environment and falls back gracefully to the prebuilt bundle — the same way it already handles Docker environments where sources are absent.

Actual behavior

The build fails with:

> [email protected] canvas:a2ui:bundle
> bash scripts/bundle-a2ui.sh

scripts/bundle-a2ui.sh: line 35: node: command not found
A2UI bundling failed. Re-run with: pnpm canvas:a2ui:bundle

After any workaround that makes compute_hash pass, a second failure emerges from pnpm's own shell wrapper also needing node:

/mnt/c/Users/<user>/AppData/Local/pnpm/.tools/pnpm/10.23.0/bin/pnpm: 15: exec: node: not found
A2UI bundling failed. Re-run with: pnpm canvas:a2ui:bundle
ELIFECYCLE  Command failed with exit code 1.

Root cause chain:

  1. pnpm executes bash scripts/bundle-a2ui.sh from Windows cmd context.
  2. Windows resolves bash to C:\Windows\System32\bash.exe, which opens WSL bash — not Git Bash.
  3. Inside WSL bash, node is not installed natively.
  4. scripts/bundle-a2ui.sh calls node --input-type=module inside compute_hash()node: command not found.
  5. Even after patching compute_hash, the subsequent pnpm -s exec tsc and pnpm -s dlx rolldown calls invoke pnpm's own shell wrapper, which also does exec node internally and fails for the same reason.

OpenClaw version

2026.2.22

Operating system

Windows 11 with WSL2 (Ubuntu). Node.js 24.13.1 on Windows/Git Bash; no node in WSL.

Install method

pnpm dev (source build from main branch)

Logs

D:\project\openclaw> pnpm build

> [email protected] canvas:a2ui:bundle
> bash scripts/bundle-a2ui.sh

# Failure 1 — node called directly in compute_hash (line 35):
scripts/bundle-a2ui.sh: line 35: node: command not found
A2UI bundling failed. Re-run with: pnpm canvas:a2ui:bundle

# Failure 2 — after patching compute_hash, pnpm wrappers also need node:
/mnt/c/Users/11635/AppData/Local/pnpm/.tools/pnpm/10.23.0/bin/pnpm: 15: exec: node: not found
A2UI bundling failed. Re-run with: pnpm canvas:a2ui:bundle
ELIFECYCLE  Command failed with exit code 1.

# Confirm: bash invoked by pnpm IS WSL, not Git Bash:
$ uname -a   # inside the bash subprocess pnpm spawns
Linux ... Microsoft ... WSL2

Impact and severity

  • Affected: All Windows developers who have WSL2 installed alongside Git Bash (a very common setup).
  • Severity: High — pnpm build is completely blocked; the project cannot be built from source on Windows.
  • Frequency: 100% reproducible on any Windows machine where bash in the system PATH resolves to WSL (the default when WSL2 is installed, since C:\Windows\System32 comes before Git Bash in PATH).
  • Consequence: Windows developers cannot build or contribute to the project without a workaround.

Suggested fix

Two complementary changes to scripts/bundle-a2ui.sh:

1. Replace the Node.js-based compute_hash with a pure-bash sha256sum implementation (removes the node dependency from hash computation entirely; sha256sum is available natively in both WSL and Git Bash):

_sha256() {
  if command -v sha256sum &>/dev/null; then
    sha256sum "$@"
  else
    shasum -a 256 "$@"   # macOS fallback
  fi
}

compute_hash() {
  (
    for input_path in "${INPUT_PATHS[@]}"; do
      if [[ -d "$input_path" ]]; then
        while IFS= read -r -d '' f; do
          printf '%s\0' "${f#"$ROOT_DIR/"}"
          _sha256 < "$f" | cut -d' ' -f1
          printf '\0'
        done < <(find "$input_path" -type f -print0 2>/dev/null | sort -z)
      elif [[ -f "$input_path" ]]; then
        printf '%s\0' "${input_path#"$ROOT_DIR/"}"
        _sha256 < "$input_path" | cut -d' ' -f1
        printf '\0'
      fi
    done
  ) | _sha256 | cut -d' ' -f1
}

2. Add WSL detection after the existing Docker fallback block, mirroring its pattern:

# WSL detection: pnpm on Windows resolves "bash" to WSL bash (System32/bash.exe),
# where native Node.js is typically absent and pnpm wrappers (tsc/rolldown) fail.
# Use the prebuilt bundle if available; otherwise guide the user to build outside WSL.
if grep -qi microsoft /proc/version 2>/dev/null; then
  if [[ -f "$OUTPUT_FILE" ]]; then
    echo "A2UI bundle up to date; skipping (WSL detected, using prebuilt bundle)."
    exit 0
  fi
  echo "WSL environment detected but no prebuilt bundle found at: $OUTPUT_FILE" >&2
  echo "Run outside WSL to build it: open Git Bash and run: pnpm canvas:a2ui:bundle" >&2
  exit 1
fi

Detection note: grep -qi microsoft /proc/version correctly identifies WSL1 and WSL2 while leaving Git Bash (MINGW64_NT) and native Linux untouched.

A PR with this fix can be provided if helpful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions