You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Prevents two non-interactive Windows environment probes from inheriting the parent process's stdin.
Under ACP stdio, stdin is a long-lived pipe owned by the client. The Git Bash and Mandatory ASLR probes used subprocess.run(..., capture_output=True) without isolating stdin, so their child processes could inherit that pipe and deadlock during the first file-tool environment initialization.
Both probes now use stdin=subprocess.DEVNULL, matching the existing isolation used by the real Git Bash session.
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 the full Python test suite; all 60 branch-relevant tests pass (the local full-suite run had unrelated environment/baseline failures)
I've added tests for my changes (required for bug fixes, strongly encouraged for features)
I've tested on my platform: macOS 15.1
Documentation & Housekeeping
I've updated relevant documentation (README, docs/, docstrings), N/A because behavior and configuration contracts are unchanged
I've updated cli-config.yaml.example if I added/changed config keys, N/A
I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows, N/A
I've considered cross-platform impact (Windows, macOS) per the compatibility guide
I've updated tool descriptions/schemas if I changed tool behavior, N/A
Screenshots / Logs
TDD evidence:
Before the production change, both focused assertions failed with KeyError: 'stdin'.
After the change, the relevant shell and subprocess suites passed: 60 passed, 0 failed.
The full Python suite completed locally: 39,826 passed, 4,871 failed; the failures were unrelated environment/baseline failures (including missing async/optional dependencies and sandbox restrictions), with a representative failure reproduced on clean upstream/main.
Ruff passed for both changed files.
The Windows footgun scan passed for both changed files.
git diff --check upstream/main...HEAD passed.
The fix was validated through focused unit and cross-platform shell tests on macOS. A native Windows ACP end-to-end run was not available in this environment.
Related: #69083 and #69732. This focused DEVNULL repair overlaps the broader bounded-probe work in #69083; it is recorded as a subset/related alternative rather than a duplicate.
Thanks for the focused Windows ACP hardening. Current main still has the stated inherited-stdin gap: _mandatory_aslr_enabled() calls subprocess.run() without stdin at tools/environments/local.py:826-838, and _bash_starts() does the same for the external MSYS probe at tools/environments/local.py:898-904. The PR adds stdin=subprocess.DEVNULL to both sites and test assertions for each in tests/tools/test_find_shell.py.
tools/environments/local.py has only these two subprocess.run() call sites, so the patch covers the complete local-environment probe set. This is consistent with the existing non-interactive spawn contract in LocalEnvironment._run_bash() (tools/environments/local.py:1480).
The scope is intentionally narrower than related open PR #69083: it isolates inherited stdin but does not replace the capture_output=True / timeout cleanup path. That is not a defect in this PR's stated change.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
backend/localLocal shell executioncomp/acpAgent Communication Protocol adapterP2Medium — degraded but workaround existsplatform/windowsNative Windows-specific behavior or breakagesweeper:blast-moderateSweeper blast radius: moderate — a subsystem or single platformsweeper:risk-platform-windowsSweeper risk: may break or behave differently on native Windowstool/fileFile tools (read, write, patch, search)type/bugSomething isn't working
3 participants
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Prevents two non-interactive Windows environment probes from inheriting the parent process's stdin.
Under ACP stdio, stdin is a long-lived pipe owned by the client. The Git Bash and Mandatory ASLR probes used
subprocess.run(..., capture_output=True)without isolating stdin, so their child processes could inherit that pipe and deadlock during the first file-tool environment initialization.Both probes now use
stdin=subprocess.DEVNULL, matching the existing isolation used by the real Git Bash session.Related Issue
Fixes #69732
Type of Change
Changes Made
tools/environments/local.py: detach stdin for the Git Bash external-program probe and the Windows Mandatory ASLR probe.tests/tools/test_find_shell.py: assert both non-interactive probes passsubprocess.DEVNULL.How to Test
scripts/run_tests.sh tests/tools/test_find_shell.py tests/tools/test_local_env_windows_msys.py tests/tools/test_subprocess_stdin_guard.py -q.ruff check tools/environments/local.py tests/tools/test_find_shell.py.python scripts/check-windows-footguns.py tools/environments/local.py tests/tools/test_find_shell.py.Checklist
Code
fix(scope):,feat(scope):, etc.)Documentation & Housekeeping
docs/, docstrings), N/A because behavior and configuration contracts are unchangedcli-config.yaml.exampleif I added/changed config keys, N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows, N/AScreenshots / Logs
TDD evidence:
KeyError: 'stdin'.60 passed, 0 failed.39,826 passed, 4,871 failed; the failures were unrelated environment/baseline failures (including missing async/optional dependencies and sandbox restrictions), with a representative failure reproduced on cleanupstream/main.git diff --check upstream/main...HEADpassed.The fix was validated through focused unit and cross-platform shell tests on macOS. A native Windows ACP end-to-end run was not available in this environment.