Skip to content

fix: support Windows executable resolution, process-tree termination, and process_is_alive Win32 API - #3

Open
Adityakk9031 wants to merge 2 commits into
AlmanacCode:mainfrom
Adityakk9031:#2
Open

fix: support Windows executable resolution, process-tree termination, and process_is_alive Win32 API#3
Adityakk9031 wants to merge 2 commits into
AlmanacCode:mainfrom
Adityakk9031:#2

Conversation

@Adityakk9031

@Adityakk9031 Adityakk9031 commented Jul 18, 2026

Copy link
Copy Markdown

Description

This PR makes provider process management and lifetime tracking fully compatible with Windows hosts.

Key changes:

  1. Windows Executable Resolution (resolve_executable): Resolves command names using shutil.which on Windows so npm .CMD/.BAT shims (e.g. codex.cmd, claude.cmd) are found on PATH without security vulnerabilities from working directory shadowing.
  2. Process Liveness (process_is_alive): Uses native Win32 APIs (kernel32.OpenProcess and GetExitCodeProcess) via ctypes to safely query PID status without raising OSError: [WinError 87].
  3. Process Tree Termination (kill_process_tree): Uses taskkill /PID <pid> /T /F on Windows to cleanly terminate entire process trees (including npm wrapper shims and descendant child processes), and process groups on POSIX.
  4. Readiness Bounded Execution: Prevents claude auth status or codex readiness checks from hanging indefinitely when stdout is piped on Windows.

Testing

  • Unit test coverage in tests/test_executable_resolution.py for executable resolution, PATHEXT shim finding, process tree termination, and working directory shadow prevention.
  • Verified tests/test_runtime_deployments.py passes cleanly on Windows.

Fixes #2

### Description
This PR fixes a critical crash that occurs on Windows when Yoke attempts to clean up stale temporary deployments.

When `os.kill(pid, 0)` is used to check if a process is alive on Windows, checking a non-existent PID raises `OSError: [WinError 87] The parameter is incorrect` instead of `ProcessLookupError` as it does on Unix. Because this exception was previously uncaught, `deploy_runtime` would crash entirely if there were stale deployment directories in the temp folder left over from dead processes.

This change catches `OSError` in `process_is_alive`, correctly treating the process as dead on Windows and allowing the garbage collection of the temporary directories to proceed smoothly.

### Testing
- [x] Verified that `pytest tests/test_runtime_deployments.py::test_runtime_deployment_reclaims_only_dead_owned_directories` now passes successfully on Windows without raising `WinError 87`.

### Related Issues
Fixes #[Insert Issue Number Here]
@Adityakk9031

Copy link
Copy Markdown
Author

@divitsheth have a look

@Adityakk9031

Copy link
Copy Markdown
Author

@rohans0509 have a look

@Adityakk9031 Adityakk9031 changed the title fix: handle WinError 87 in process_is_alive on Windows fix: support Windows executable resolution, process-tree termination, and process_is_alive Win32 API Aug 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: process_is_alive crashes Yoke runtime deployments on Windows (OSError: [WinError 87])

1 participant