Skip to content

fix: preserve POSIX rg paths for remote backends on Windows - #84557

Open
guoyutw wants to merge 1 commit into
NousResearch:mainfrom
guoyutw:fix/windows-remote-rg-paths
Open

fix: preserve POSIX rg paths for remote backends on Windows#84557
guoyutw wants to merge 1 commit into
NousResearch:mainfrom
guoyutw:fix/windows-remote-rg-paths

Conversation

@guoyutw

@guoyutw guoyutw commented Aug 12, 2026

Copy link
Copy Markdown

Summary

Problem

PR #84378 correctly fixed native Windows rg path handling. However, the Windows-native conversion was selected from the controller host OS rather than the actual execution backend.

For a Windows controller using an SSH or other non-local POSIX backend, a target such as:

/c/remote/project

could be rewritten as:

C:/remote/project

/c/remote/project may be a legitimate POSIX path on the remote backend. It must not be interpreted as an MSYS drive path merely because the controller host is Windows.

Fix

Limit Windows-native rg target conversion to LocalEnvironment when running on Windows.

Non-local backends retain the existing _escape_shell_arg() behavior and therefore preserve POSIX/Bash-safe target paths.

This is a narrow follow-up to PR #84378, not a replacement or redesign of that fix.

Testing

  • Deterministic SSH/remote regression:
    • /c/remote/project remains /c/remote/project
    • it is not converted to C:/remote/project
  • Local Windows regression:
    • C:\Users\fixture\target → C:/Users/fixture/target
  • Local Windows forward-slash regression:
    • C:/Users/fixture/target remains native
  • Real Windows production-path regression:
    • content search: PASS
    • files search: PASS
    • zero-result search: PASS
    • error is None: PASS
    • no runtime os error 3: PASS
  • Focused final slice: 19 passed
  • compileall: PASS
  • git diff --check: PASS

Related

This change addresses the demonstrated backend-boundary path-conversion gap and does not claim to resolve issues beyond that scope.

@alt-glitch alt-glitch added type/bug Something isn't working tool/file File tools (read, write, patch, search) backend/local Local shell execution backend/ssh SSH remote execution platform/windows Native Windows-specific behavior or breakage P2 Medium — degraded but workaround exists sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows labels Aug 12, 2026

@monerostar monerostar 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.

Native Windows 11 verification

Host: Windows 11 (Windows-10-10.0.26200-SP0), CPython 3.11.15, worktree ab6019d7b. Native rg is on PATH via WinGet: ripgrep 15.1.0 (C:\Users\Admin\AppData\Local\Microsoft\WinGet\Packages\...\rg.EXE).

Gap on current main

tools/file_operations.py::_escape_native_tool_arg on upstream main is still:

if _IS_WINDOWS and arg:
    arg = _msys_to_windows_path(arg).replace("\\", "/")

That keys off the controller OS, not the execution backend. Live helper on this box:

_msys_to_windows_path("/c/remote/project") -> C:\remote\project
_msys_to_windows_path("/c/Users/Admin")    -> C:\Users\Admin

So a Windows controller talking to SSH/Docker would rewrite a legitimate remote POSIX path /c/remote/project into C:/remote/project. That is the bug this PR names.

After this PR

Mocked SSHEnvironment search for /c/remote/project captured:

rg --files ... '/c/remote/project'

No C:/remote/project.

Mocked LocalEnvironment search for C:\Users\Admin captured:

rg --files ... 'C:/Users/Admin'

Local native conversion from #84378 is preserved.

Live LocalEnvironment → native rg

Temp dir C:\Users\Admin\AppData\Local\Temp\rg84557_ufcm_5fm with NATIVE_RG_LIVE_TOKEN in native-rg-live.txt:

search result
content NATIVE_RG_LIVE_TOKEN error=None, count=1
files native-rg-live.txt error=None, hit C:/Users/Admin/AppData/Local/Temp/rg84557_ufcm_5fm\native-rg-live.txt
absent token error=None, count=0
rg --version via LocalEnvironment rc 0, ripgrep 15.1.0

No os error 3.

Tests

python -m pytest tests/tools/test_file_operations.py::TestEscapeNativeToolArg \
  tests/tools/test_file_tools_live.py::TestWindowsNativeRgLiveSearch \
  -q --tb=short -o addopts=
10 passed in 4.26s

Review notes

  • Narrow follow-up to #84378: keep the local Windows native spelling, stop leaking it into remote POSIX backends. isinstance(self.env, LocalEnvironment) is the right boundary.
  • MagicMock in older tests is now spec=LocalEnvironment, which is what makes the new guard testable.
  • I cannot exercise a real SSH backend on this machine tonight; the mock + the live _msys_to_windows_path conversion is the evidence that main would have rewritten /c/remote/project.

I cannot merge. From native Win11 the local path is solid and the remote-preservation change matches the demonstrated gap.

CI note: no checks reported on the head branch. Local slice above is green.

@Enough1122

Copy link
Copy Markdown
Contributor

AI code review — automated review for reference, author can ignore or act on any point.

fix: preserve POSIX rg paths for remote backends on Windows

  1. tools/file_operations.py::_escape_native_tool_arg — the new gate isinstance(self.env, LocalEnvironment) is a concrete-class check. Any wrapper/decorator that proxies a local backend without subclassing LocalEnvironment (the codebase already has delegation-style wrappers; the live-test RecordingLocalEnvironment only works because it subclasses) would silently lose the _msys_to_windows_path conversion on a local Windows controller. A capability attribute on the environment (e.g. an is_local_filesystem property or a supports_native_paths flag) would be more robust than the isinstance check.
  2. The behavior change is broader than the reported symptom: every non-LocalEnvironment backend driven from a Windows controller (including a hypothetical future Docker local driver that executes on the Windows host, or any env proxy) now falls through to _escape_shell_arg with no msys conversion. Worth confirming no other code path relied on the conversion for those backends.
  3. The non-Windows/local fallthrough now calls self._escape_shell_arg(arg); the pre-existing non-Windows branch previously produced '...' quoting via the same expression, so equivalence holds, but a one-line comment noting _escape_shell_arg is the same quoting implementation would prevent a future divergence.
  4. Minor: the new test_remote_posix_path_is_not_converted_on_windows_controller monkeypatches tools.environments.local._IS_WINDOWS and runs on all platforms — good. The live Windows rg test is conditional on rg being on PATH (skips otherwise), so coverage is tooling-dependent; that's acceptable but worth stating in the docstring.

@guoyutw

guoyutw commented Aug 16, 2026

Copy link
Copy Markdown
Author

@Enough1122 Thanks for calling out the concrete isinstance(LocalEnvironment) extensibility concern.

I completed a read-only audit of the production Environment implementations and all _escape_native_tool_arg() call sites. LocalEnvironment is currently the only production backend that executes commands directly on the controller host. Docker, SSH, Modal, Daytona, Vercel, and Singularity execute in their target backend, so command/path authority belongs there rather than to the Windows controller. There is currently no production non-subclass local wrapper/proxy; delegation aliases share the original environment instance.

For the current architecture, isinstance(LocalEnvironment) is therefore the correct and smallest boundary. Adding supports_native_paths or is_local_filesystem now would expand the public abstraction surface for a hypothetical backend.

This is a valid future extensibility concern, but not a current correctness gap. If a non-subclass local proxy or Windows-native remote backend is introduced, it should add the capability seam together with path-authority tests.

Existing tests cover Windows local conversion, Windows-controller/remote-POSIX preservation, non-Windows quoting equivalence, and live Windows rg paths; the live test explicitly skips when rg is unavailable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend/local Local shell execution backend/ssh SSH remote execution P2 Medium — degraded but workaround exists platform/windows Native Windows-specific behavior or breakage sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows tool/file File tools (read, write, patch, search) type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants