Skip to content

ctx_execute fails to spawn python/node on Windows when only shell-script shims are on PATH (misleading 'not found in $PATH' error) #1208

Description

@fl4pj4ck

Summary

ctx_execute (and ctx_execute_file) fail to spawn the python, python3, and node language runners on Windows when the only interpreters resolvable on PATH are Git-for-Windows-style POSIX shell-script shims (the common shape produced by pyenv-win, some Python launcher setups, and Git Bash's own /usr/bin/python* wrappers). The tool reports Executable not found in $PATH: "python", which is misleading and sent me down a multi-hour path of "fix your PATH" when the interpreters were already valid and resolvable by every other tool on the machine (bash, which, etc.).

Root cause

The language runner spawns the interpreter via a native Windows process-creation call with no shell mediation (Node/Bun child_process.execFileSync/spawn with shell:false, effectively CreateProcess). That resolution path:

  • Requires the target to have a real extension (.exe/.com/.bat/.cmd) — a bare extensionless file (even a valid, executable-via-bash POSIX shell script) is invisible to it.
  • Does not fall back to a shell (cmd.exe) that would have resolved PATHEXT correctly and executed the shim.

So on any Windows box where Python/Node were installed via a wrapper-script pattern (extensionless, shebang-based python/python3/node on PATH, common with Git for Windows), ctx_execute(language:"python") and ctx_execute(language:"javascript") fail outright even though the interpreter is fully functional and on PATH for every other purpose.

Reproduction

Environment: Windows 11, Git for Windows (MSYS2) installed, Python 3.14 and Node 24 installed via their official installers but exposed on PATH only through Git Bash-style #!/bin/sh wrapper scripts at C:\Program Files\Git\usr\bin\python, python3, node (no .exe extension).

ctx_execute(language: "python", code: "print(1)")

Result:

Exit code: 1
stderr:
Executable not found in $PATH: "python"

Yet in the same environment:

ctx_execute(language: "shell", code: "python --version")

succeeds and prints Python 3.14.7, because bash resolves the extensionless shim directly.

I also reproduced the identical failure shape independently for node:

// ctx_execute(language: "javascript")
const { execFileSync } = require('child_process');
execFileSync('node', ['--version'], { shell: false }); // throws "Executable not found in $PATH: node"

while execFileSync('node', ['--version']) succeeds when a real .exe is on PATH.

Impact

  • The error message ("not found in $PATH") is actively misleading: the executable is found by every other consumer of PATH on the machine. The actual condition is "found, but not natively spawnable without shell mediation."
  • This silently breaks ctx_execute(language:"python"/"javascript"/"typescript") for a fairly common real-world Windows dev environment shape (Git for Windows + python.org/nodejs.org installers, no bundled/embedded interpreter), with no actionable guidance in the error toward the real cause.
  • Working around it currently requires hand-placing hard-linked .exe files (and, for CPython specifically, the interpreter's dependent DLL) directly into a directory already on the restricted PATH the sandboxed spawn actually inherits — which is a fragile, environment-specific hack, not something a normal user should have to reverse-engineer.

Suggested fix

For the python/node/etc. language runners on Windows, either:

  1. Fall back to a shell-mediated spawn (shell: true, or explicit cmd.exe /c) when a direct non-shell spawn reports "not found," before surfacing an error, so PATHEXT-based and shim-based resolution gets a chance; or
  2. At minimum, distinguish in the error message between "no candidate found on PATH at all" and "a candidate exists on PATH but couldn't be spawned without shell mediation" (e.g. by doing a where/command -v-equivalent check first), so users aren't misdirected into "fix your PATH" when PATH was never the problem.

Environment

  • context-mode v1.0.169
  • OS: Windows 11
  • Shell integration: Git for Windows / MSYS2 (Git Bash)
  • ctx_doctor output at time of report:
    [OK] Runtimes: 5/11 (45%) — javascript, shell, typescript, python, rust
    [OK] Performance: FAST (Bun)
    [OK] Server test: PASS
    [OK] FTS5 / SQLite: PASS — native module works
    
    (Runtime detection reported these as "OK" despite the underlying native spawn failing — the detection check itself appears to accept a shim that the actual exec path can't use, which is worth verifying as a related gap.)

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions