@@ -169,6 +169,14 @@ def find_command_robust(cmd: str, fallback_paths: list[str] | None = None) -> st
169169 for attempt in range (2 ):
170170 cmd_path = shutil .which (cmd )
171171 if cmd_path :
172+ # Normalize extension case on Windows for Git Bash compatibility
173+ # shutil.which() uses Windows PATHEXT which has uppercase extensions (.EXE)
174+ # but Git Bash is case-sensitive and needs lowercase (.exe)
175+ if sys .platform == 'win32' :
176+ path_obj = Path (cmd_path )
177+ ext = path_obj .suffix
178+ if ext .upper () in ['.EXE' , '.CMD' , '.BAT' , '.COM' ] and ext != ext .lower ():
179+ cmd_path = str (path_obj .with_suffix (ext .lower ()))
172180 return cmd_path
173181
174182 # Brief delay for PATH synchronization (especially on Windows)
@@ -325,18 +333,25 @@ def compare_versions(current: str, required: str) -> bool:
325333
326334# Windows-specific functions
327335def find_bash_windows () -> str | None :
328- """Find Git Bash on Windows."""
329- # Check CLAUDE_CODE_GIT_BASH_PATH env var
336+ """Find Git Bash on Windows.
337+
338+ Git Bash is required for Claude Code on Windows and provides consistent
339+ cross-platform bash behavior for CLI command execution.
340+
341+ Returns:
342+ Full path to bash.exe if found, None otherwise.
343+
344+ Note:
345+ Prioritizes Git Bash locations over PATH search to avoid
346+ accidentally finding WSL's bash.exe at C:\\ Windows\\ System32.
347+ """
348+ # Check CLAUDE_CODE_GIT_BASH_PATH env var first
330349 env_path = os .environ .get ('CLAUDE_CODE_GIT_BASH_PATH' )
331350 if env_path and Path (env_path ).exists ():
332351 return str (Path (env_path ).resolve ())
333352
334- # Check if bash is in PATH
335- bash_path = find_command ('bash.exe' )
336- if bash_path :
337- return bash_path
338-
339- # Check common locations
353+ # Check Git Bash common locations FIRST (before PATH search)
354+ # This prevents accidentally finding WSL's bash.exe in System32
340355 common_paths = [
341356 r'C:\Program Files\Git\bin\bash.exe' ,
342357 r'C:\Program Files\Git\usr\bin\bash.exe' ,
@@ -351,6 +366,15 @@ def find_bash_windows() -> str | None:
351366 if Path (expanded ).exists ():
352367 return str (Path (expanded ).resolve ())
353368
369+ # Fall back to PATH search (may find Git Bash if installed elsewhere)
370+ bash_path = find_command ('bash.exe' )
371+ if bash_path :
372+ # Skip WSL bash in System32/SysWOW64
373+ bash_lower = bash_path .lower ()
374+ if 'system32' not in bash_lower and 'syswow64' not in bash_lower :
375+ return bash_path
376+ # WSL bash found - don't use it, return None instead
377+
354378 return None
355379
356380
0 commit comments