fix(tools): stop search_files failing on absolute Windows paths under Git Bash - #80314
fix(tools): stop search_files failing on absolute Windows paths under Git Bash#80314fangliquanflq wants to merge 2 commits into
Conversation
Native Win11 verification (monerostar)Host: physical Windows 11 build 26200, CPython 3.11.15 ( Bug class still real under Hermes defaultsHermes sets On this branch, the shell vs native split is correct: Live
|
| path form | n_matches |
|---|---|
C:\Users\Admin\src\hermes-agent-contrib\tools |
5 |
C:/Users/Admin/src/hermes-agent-contrib/tools |
5 |
/c/Users/Admin/src/hermes-agent-contrib/tools |
5 |
relative tools |
5 |
Focused tests
pytest tests/tools/test_local_env_windows_msys.py::TestWin32ToolPath \
tests/tools/test_file_operations.py -k "Win32Tool or win32_safe or escape_native or search_with_rg_passes or search_files_rg_passes or zero_match_probe_passes" \
-o addopts= -v
# 9 passed
CI on the PR is green (All required checks pass).
Cluster note
Triage flagged overlap with #67914 / related search-files Windows path work. This PR’s split (_bash_safe_path for bash builtins vs _win32_tool_path / _escape_native_tool_arg for Win32 rg) matches the actual failure mode on this host. Whichever sibling merges, please keep the Win32-safe rg path form — MSYS /c/... must not be passed to rg.exe under MSYS_NO_PATHCONV.
Verdict: LGTM from native Win11. Could not leave a formal Approve (fork collaborator scope) — evidence review as comment.
|
Thanks for the verification. This is a real issue I've hit in normal use - it can seriously slow down agent inference. For now I'm working around it via skills. |
monerostar
left a comment
There was a problem hiding this comment.
Native Win11 live-verify (monerostar)
Host: Windows 11 build 26200 · Git Bash · ripgrep 15.1.0 (Win32) · install tree %LOCALAPPDATA%\hermes\hermes-agent
PR tip: 34c11a5d0 · control: live install main (same box)
Bug still on main
Absolute path content search rewrites to /c/... for bash, then hands that to native rg.exe under MSYS_NO_PATHCONV → IO error. File search fails silent (total=0, err=None).
Fixture: %LOCALAPPDATA%\Temp\hermes-rg-path-repro\subdir\sample.txt needle needle-xyz-unique-content-67914
| path form | main content | main files *.txt |
PR content | PR files |
|---|---|---|---|---|
C:\...\hermes-rg-path-repro |
err os error 2 on /c/... |
total 0 silent | total 1 | total 2 |
C:/... |
same fail | silent 0 | total 1 | total 2 |
/c/... |
same fail | silent 0 | total 1 | total 2 |
Helper on PR: _escape_native_tool_arg maps all three → 'C:/Users/.../hermes-rg-path-repro'. _escape_shell_arg still MSYS for bash builtins (correct split).
Tests
Path-escape focused: 4 passed.
Broader -k path|msys|windows|escape|rg|native: 36 passed; 3 failed look orthogonal (hidden-root fallback empty set; PortableGit PATH expects /pg/usr/bin vs backslash form on this host). Not blaming the rg path fix.
CI on the PR: green (30 success).
Sibling
#78224 also fixes the live matrix on this box, but is thinner (no local.py path helpers, mergeState BLOCKED, empty checks when I looked). Prefer this PR; cross-link only.
Looks good from this daily driver.
monerostar
left a comment
There was a problem hiding this comment.
Sibling pointer (monerostar)
Re-checked 2026-08-11 on native Win11: this tip is still CONFLICTING/DIRTY vs current main.
Fresh absolute-path matrix (same fixture as before) now lands cleanly on #78224 @ e228895a8 (MERGEABLE), including _quote_rg_path for content + files + zero-match probe routing.
Prefer the mergeable tip for landing; rebase/refresh here if you want this helper shape (_escape_native_tool_arg) instead.
search_files rewrote drive paths to /c/... for Git Bash, but native Win32 rg.exe uses CreateFile under MSYS_NO_PATHCONV and rejects those mounts. Keep bash builtins on /c/...; quote C:/... for rg argv.
34c11a5 to
6f74322
Compare
|
@monerostar Thanks for the re-check and the sibling pointer. Rebased this branch onto current Tip is now |
|
Closing as implemented on main: #84378 (merged) covers this fix — a shared native-path escaper (_escape_native_tool_arg) applied to all six rg call sites, the zero-match probes, and the shell linter interpolation, with Windows regression tests. Thank you for diagnosing this — your PR correctly identified the same root cause (native binaries + MSYS_NO_PATHCONV means /c/... is never translated back), and the merged fix lands the same approach across the full call-site set. Sorry we couldn't land this one directly. |
What does this PR do?
On native Windows with Git Bash,
search_filesfailed when given absolute drive paths (C:\...or/c/...). The tool rewrote those paths to MSYS form for bash, then passed the quoted/c/...argv to Win32rg.exe. With Hermes' defaultMSYS_NO_PATHCONV, CreateFile does not understand MSYS mounts, so searches returned IO errors even thoughcd /c/...worked in the same shell.Bug Cause
_escape_shell_argrewrites drive paths to/c/...so bash builtins (sed,test,find, GNUgrep) resolve correctly. That form is wrong for Win32 ripgrep underMSYS_NO_PATHCONV=1/MSYS2_ARG_CONV_EXCL=*: quoted/c/...is passed through unchanged and CreateFile fails with os error 3. Relative paths still worked because they never triggered the drive rewrite.Fix
Add
_win32_tool_path/_escape_native_tool_argand use them for everyrgsearch-root path (_search_with_rg,_search_files_rg,_zero_match_probe). Bash builtins keep_escape_shell_arg(/c/...). Off-Windows behavior is unchanged.Related Issue
N/A
Type of Change
Changes Made
tools/environments/local.py- add_win32_tool_pathto normalize MSYS/Cygwin/WSL drive paths to forward-slashC:/...for Win32 toolstools/file_operations.py- add_escape_native_tool_arg; pass Win32-safe paths to allrginvocations; leave bash/find/grep on/c/...tests/tools/test_local_env_windows_msys.py- cover_win32_tool_pathincluding/cygdriveand/mntformstests/tools/test_file_operations.py- assert content search, file search, and zero-match probes quoteC:/...not/c/...How to Test
rgon PATH, from a Hermes checkout:search_fileswithpath=/c/<drive>/.../<repo>/toolsand a known pattern -> matches (notIO error ... os error 3)path=C:\...\tools-> matchespath=tools-> still matchesscripts/run_tests.sh tests/tools/test_local_env_windows_msys.py tests/tools/test_file_operations.py -q # focused Win32 path nodes also: pytest -k "Win32Tool or win32_safe" -qChecklist
Code
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests passDocumentation & Housekeeping
docs/, docstrings) — or N/Acli-config.yaml.exampleif I added/changed config keys — or N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — or N/A