Skip to content

fix(terminal): prefer Scoop MSYS bash over WSL bash on Windows - #35675

Open
sunnirvana wants to merge 1 commit into
NousResearch:mainfrom
sunnirvana:fix/windows-bash-priority-msys-scoop
Open

fix(terminal): prefer Scoop MSYS bash over WSL bash on Windows#35675
sunnirvana wants to merge 1 commit into
NousResearch:mainfrom
sunnirvana:fix/windows-bash-priority-msys-scoop

Conversation

@sunnirvana

@sunnirvana sunnirvana commented May 31, 2026

Copy link
Copy Markdown

On Windows hosts with WSL and Scoop Git installed side-by-side, shutil.which('bash') may return /usr/bin/bash (Linux ELF from WSL) which cannot be executed by Python running on the Windows side.

Fixes three related issues:

  • _find_bash() now checks Scoop-managed Git before shutil.which
  • base.py skips redundant cd for Windows cwd when using WSL bash
  • file_operations.py bypasses bash cwd for Windows absolute paths

Health-check job fails with: cd: /c/Users/.../hermes: No such file or directory

What does this PR do?

Related Issue

Fixes #

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

How to Test

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform:

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

For New Skills

  • This skill is broadly useful to most users (if bundled) — see Contributing Guide
  • SKILL.md follows the standard format (frontmatter, trigger conditions, steps, pitfalls)
  • No external dependencies that aren't already available (prefer stdlib, curl, existing Hermes tools)
  • I've tested the skill end-to-end: hermes --toolsets skills -q "Use the X skill to do Y"

Screenshots / Logs

On Windows hosts with WSL and Scoop Git installed side-by-side,
shutil.which('bash') may return /usr/bin/bash (Linux ELF from WSL)
which cannot be executed by Python running on the Windows side.

Fixes three related issues:
- _find_bash() now checks Scoop-managed Git before shutil.which
- base.py skips redundant cd for Windows cwd when using WSL bash
- file_operations.py bypasses bash cwd for Windows absolute paths

Health-check job fails with: cd: /c/Users/.../hermes: No such file or directory
@alt-glitch alt-glitch added type/bug Something isn't working tool/terminal Terminal execution and process management tool/file File tools (read, write, patch, search) backend/local Local shell execution P2 Medium — degraded but workaround exists labels May 31, 2026

@tonydwb tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

Verdict: Approved

Overview

Fixes three related Windows terminal issues: Scoop Git bash priority (avoids picking WSL's Linux ELF bash), skipping redundant builtin cd for Windows cwd in WSL bash sessions, and bypassing bash cwd entirely for Windows absolute paths in write_file.

Looks Good

  • _find_bash(): Scoop Git check before shutil.which — correct priority
  • base.py: Detects Windows cwd via [A-Za-z]:[/\\] regex, skips cd that would fail in WSL bash
  • file_operations.py: Native Python I/O for Windows absolute paths — avoids bash cwd entirely, with full write + lint + LSP pipeline
  • Good edge case handling throughout
  • Well-commented rationale at each change point

Caveats

  • PR description template is mostly unfilled (missing issue number, test steps)
  • No tests for the new Windows I/O path in file_operations
  • However, this is a platform-specific fix on a code path that previously didn't work at all — the approach is sound

Reviewed by Hermes Agent

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for identifying the Scoop + WSL lookup case. The Scoop-specific gap is still present: current tools/environments/local.py:596 reaches shutil.which("bash") without a Scoop Git candidate, so WSL can still win when it appears earlier on PATH.

Problems

  • The base.py and file_operations.py portions are stale against current main. Current code converts native cwd values through LocalEnvironment._quote_cwd_for_cd (tools/environments/local.py:1022) and rewrites file-operation paths before using the atomic write pipeline (tools/file_operations.py:960, tools/file_operations.py:977). The PR's direct open(..., "w") path should not be transplanted over that pipeline.
  • The PR has no regression coverage for the Scoop-before-WSL ordering.

Suggested changes

  • Salvage the Scoop candidate narrowly before _find_bash() falls back to shutil.which("bash"), preserving the current path conversion and write mechanisms.
  • Add a mocked Windows test where Scoop Git exists and shutil.which("bash") resolves to WSL, asserting Scoop wins.

Automated hermes-sweeper review.

_scoop_git = os.path.join(_userprofile, "scoop", "apps", "git", "current", "bin", "bash.exe")
if os.path.isfile(_scoop_git):
return _scoop_git

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a regression test for this priority: mock the Scoop bash.exe path as existing while shutil.which("bash") returns the WSL launcher, then assert _find_bash() selects Scoop.

@teknium1 teknium1 added sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend/local Local shell execution P2 Medium — degraded but workaround exists sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows tool/file File tools (read, write, patch, search) tool/terminal Terminal execution and process management type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants