openai / openai/codex-plugin-cc

Windows: `cancel` silently fails — Git Bash mangles `taskkill /PID /T /F` flags, leaving jobs stuck as `running`

Open
#708 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
33.3k
Forks
2.3k
PR merge metrics
No merged PRs in 30d

Description

Summary

On Windows with Git Bash as the calling shell, codex-companion cancel never actually kills the job. It shells out taskkill /PID <n> /T /F, but MSYS (Git Bash) path-converts those flags before taskkill receives them. The command still exits cleanly, so the failure is silent — the job stays marked running in state.json indefinitely.

Reproduction

In Git Bash on Windows, any leading-slash argument handed to a native Windows executable is rewritten:

$ python -c "import sys; print(sys.argv[1:])" /PID 1234 /T /F
['C:/Program Files/Git/PID', '1234', 'T:/', 'F:/']

So the cancel path effectively invokes:

taskkill C:/Program Files/Git/PID 1234 T:/ F:/

Every flag is corrupted — /PID becomes a path inside the Git installation, and the single letters become drive roots.

Confirmed by the MSYS escape hatch, which passes them through intact:

$ MSYS_NO_PATHCONV=1 python -c "import sys; print(sys.argv[1:])" /PID 1234 /T /F
['/PID', '1234', '/T', '/F']

Impact

  • Background /codex:rescue jobs that wedge cannot be cancelled.
  • codex-companion status keeps reporting them as running (phase stuck at starting) indefinitely, and the stale record carries into later runs, so a relaunch inherits a phantom job.
  • Observed twice in separate sessions, ~30 minutes lost each time, with cancel appearing to hang or no-op. Recovery required killing the PID manually from PowerShell and hand-editing state.json.

Environment: Windows 11, codex-cli 0.151.0, codex plugin 1.0.6, Git Bash (MSYS) as the calling shell.

Suggested fix

Avoid handing MSYS-convertible flags through a shell. Options, roughly in order of robustness:

  1. Spawn taskkill with an argument array and no shell — e.g. child_process.spawn('taskkill', ['/PID', String(pid), '/T', '/F'], { shell: false }). The CreateProcess path is not subject to MSYS conversion. (Verified in Python: an arg-list subprocess call passes the identical flags through intact even when launched from Git Bash.)
  2. Set MSYS_NO_PATHCONV=1 (or MSYS2_ARG_CONV_EXCL=*) in the child environment.
  3. Use the dash form taskkill -PID <n> -T -F, which MSYS does not rewrite.

Independently of the flag issue, two robustness improvements would prevent the "permanently running" state:

  • Check taskkill's exit code and verify the PID is actually gone before reporting success.
  • Always write a terminal status, including when the process is already dead — today a dead process plus a running record requires manual state.json surgery to clear.

Possibly related (may belong in codex-cli rather than this plugin)

The jobs I needed to cancel were wedged inside task at tool discovery: the run's final event was an exec evaluating ALL_TOOLS.filter(...), which never returned (42 minutes; the session rollout file was frozen ~4s after start). The turn context was approval_policy: never, sandbox_policy: read-only, network: restricted.

The same prompt and the same MCP tools run fine via codex exec --enable code_mode_host — tool discovery completes and the MCP calls succeed under -s read-only — so the hang appears specific to the task/app-server runtime rather than to the sandbox or approval policy. Happy to open that separately against codex-cli if that's the better home for it.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Locate the cancel path that invokes Windows taskkill and reproduce it from Git Bash using the issue's command and flag examples. Verify the process is terminated without MSYS argument conversion, and confirm cancel records a terminal state when taskkill fails or the process is already gone.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
cli, operating-systems
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.