Describe the bug
BashSession.start() passes the literal string "/bin/bash" to asyncio.create_subprocess_exec as the executable (src/nooa/tools/_bash_session.py:164). That path does not exist on native Windows, so ShellTools.run() cannot start a session there.
This is not a regression and not a new break — it has never worked on Windows. It is filed because it is currently unreported: #95 mentions the pass_fds failure in passing, and its own body notes that its STEP 6/7 findings are not covered by any open issue. This is STEP 6's next failure.
Relationship to #98
#98 fixes the failure that currently masks this one. On main, start() fails first at:
AssertionError: pass_fds not supported on Windows
because start_new_session=True and pass_fds=(ctrl_w,) are passed unconditionally (lines 172-173). #98 correctly moves both behind a sys.platform != "win32" guard:
kwargs: dict[str, Any] = {}
if sys.platform != "win32":
kwargs["start_new_session"] = True
kwargs["pass_fds"] = (ctrl_w,)
That guard works — verified on a native Windows 11 host against #98's branch. But the diff leaves the "/bin/bash" argument unchanged, so the call now proceeds one step further and fails with:
FileNotFoundError: [WinError 2] The system cannot find the file specified
So #98 changes which error Windows users get, not whether ShellTools.run() works. Worth stating explicitly so #98 is not read as making the shell surface Windows-ready.
A second obstacle behind this one
Even with a bash on PATH (Git Bash, MSYS2), dropping pass_fds on Windows removes the control-channel descriptor the protocol depends on — ctrl_w is fd 3 inside bash. Making ShellTools.run() genuinely work on Windows is therefore a larger design question than substituting an executable path, which is why this issue proposes the smaller thing below.
To reproduce
On a native Windows host (no WSL), with #98's branch checked out:
import asyncio
from nooa.tools import ShellTools
asyncio.run(ShellTools().run("echo hi"))
On main the same snippet fails earlier, with the pass_fds AssertionError.
Expected behavior
Either of these would be an improvement; I'd suggest the first:
- Fail clearly. Raise an explicit, documented error on Windows — something like
ShellTools requires a POSIX shell and is not supported on native Windows; use WSL — instead of FileNotFoundError: [WinError 2], which reads like a missing user file rather than an unsupported platform.
- Resolve the shell rather than hardcoding it (
shutil.which("bash"), $SHELL), which also helps NixOS and other hosts where /bin/bash is not the canonical path — but this does not by itself make Windows work, because of the fd-3 control channel above.
Environment
Additional context
Same family as #84, #85, #92 — POSIX-only assumptions reachable from ordinary use. Unlike those, this one is not on the import nooa path, so the import smoke test in #108 will not catch it.
Describe the bug
BashSession.start()passes the literal string"/bin/bash"toasyncio.create_subprocess_execas the executable (src/nooa/tools/_bash_session.py:164). That path does not exist on native Windows, soShellTools.run()cannot start a session there.This is not a regression and not a new break — it has never worked on Windows. It is filed because it is currently unreported: #95 mentions the
pass_fdsfailure in passing, and its own body notes that its STEP 6/7 findings are not covered by any open issue. This is STEP 6's next failure.Relationship to #98
#98 fixes the failure that currently masks this one. On
main,start()fails first at:because
start_new_session=Trueandpass_fds=(ctrl_w,)are passed unconditionally (lines 172-173). #98 correctly moves both behind asys.platform != "win32"guard:That guard works — verified on a native Windows 11 host against #98's branch. But the diff leaves the
"/bin/bash"argument unchanged, so the call now proceeds one step further and fails with:So #98 changes which error Windows users get, not whether
ShellTools.run()works. Worth stating explicitly so #98 is not read as making the shell surface Windows-ready.A second obstacle behind this one
Even with a
bashon PATH (Git Bash, MSYS2), droppingpass_fdson Windows removes the control-channel descriptor the protocol depends on —ctrl_wis fd 3 inside bash. MakingShellTools.run()genuinely work on Windows is therefore a larger design question than substituting an executable path, which is why this issue proposes the smaller thing below.To reproduce
On a native Windows host (no WSL), with #98's branch checked out:
On
mainthe same snippet fails earlier, with thepass_fdsAssertionError.Expected behavior
Either of these would be an improvement; I'd suggest the first:
ShellTools requires a POSIX shell and is not supported on native Windows; use WSL— instead ofFileNotFoundError: [WinError 2], which reads like a missing user file rather than an unsupported platform.shutil.which("bash"),$SHELL), which also helps NixOS and other hosts where/bin/bashis not the canonical path — but this does not by itself make Windows work, because of the fd-3 control channel above.Environment
Harshitmishra001:fix-windows-compatibility)mainand against fix(windows): resolve POSIX-only compatibility issues (#92, #95) #98's diffAdditional context
Same family as #84, #85, #92 — POSIX-only assumptions reachable from ordinary use. Unlike those, this one is not on the
import nooapath, so the import smoke test in #108 will not catch it.