Windows: approved pytest run interrupts TUI and sends SIGINT to MCP servers

Open 💬 10 comments Opened May 3, 2026 by y-chell
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

What happened?

On Windows, Codex CLI TUI can interrupt/exit when running a full pytest command after approval/escalation. The UI shows:

Conversation interrupted - tell the model what to do differently. Something went wrong? Hit `/feedback` to report the issue.

This reproduced even after opening a fresh Codex window/session, so it does not appear to be caused by a large conversation context.

The same project test suite was later run outside this failing Codex TUI path and completed successfully:

147 passed

Environment

codex-cli 0.128.0
OS: Microsoft Windows NT 10.0.26200.0
Shell: PowerShell 7.6.1
Python: 3.14.2
Codex config: [windows] sandbox = "unelevated"
Workspace path is on E:\ drive

Reproduction context

Inside Codex TUI on Windows:

  1. Work in a Python project with a pytest suite.
  2. Ask Codex to run a full test command such as:
python -m pytest --basetemp "E:\tmp\opennovel-pytest-full-scope" -p no:cacheprovider
  1. Approve the escalation prompt.
  2. The Codex conversation is interrupted/exits instead of returning the pytest result.

Relevant Codex log evidence

From C:\Users\Administrator\.codex\log\codex-tui.log:

2026-05-03T15:12:44.527597Z ToolCall: shell_command {"command":"python -m pytest --basetemp \"E:\\tmp\\opennovel-pytest-full-scope\" -p no:cacheprovider","workdir":"E:\\xiu\\biji\\novels\\opennovel","timeout_ms":120000,"sandbox_permissions":"require_escalated" ...}
2026-05-03T15:12:50.289990Z submission_dispatch{otel.name="op.dispatch.exec_approval" ...}
2026-05-03T15:12:55.540398Z MCP server stderr (cmd): [INFO] Received SIGINT, shutting down...

There was no matching Windows Application Error crash record for codex, node, or python at that time.

Additional permission clues

Inside the Codex sandbox, writing to E:\tmp failed:

Set-Content: Access to the path 'E:\tmp\codex-write-probe.txt' is denied.

The same write probe succeeds when run with elevated/non-sandbox permissions.

The project also has a .pytest_cache directory whose ACL cannot be read from the sandbox:

warning: could not open directory '.pytest_cache/': Permission denied

Non-sandbox ACL check shows:

E:\xiu\biji\novels\opennovel\.pytest_cache NT AUTHORITY\SYSTEM:(OI)(CI)(F)
                                           BUILTIN\Administrators:(OI)(CI)(F)
                                           OWNER RIGHTS:(OI)(CI)(F)

codex --help also prints these warnings on the same machine:

WARNING: failed to clean up stale arg0 temp dirs: 拒绝访问。 (os error 5)
WARNING: proceeding, even though we could not update PATH: 拒绝访问。 (os error 5) at path "C:\Users\Administrator\.codex\tmp\arg0\codex-arg0pTKlyi"

Expected behavior

Even if the pytest command fails due to Windows sandbox permissions, Codex TUI should return the command output/error to the conversation and keep the session alive.

Actual behavior

The conversation is interrupted/exits around the approval/escalated command path, and MCP child processes receive SIGINT.

Notes

This may be related to Windows sandbox/approval handling rather than pytest itself. Targeted pytest subsets complete normally, and the full suite can pass outside this Codex TUI failure path.

View original on GitHub ↗

10 Comments

github-actions[bot] contributor · 2 months ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #20443

Powered by Codex Action

y-chell · 2 months ago

Additional impact: this is not just a single-session annoyance. The user opened a fresh Codex terminal/window for the same project and hit the same interruption again, which effectively blocks continuing work on that project from Codex TUI. The main problem is that the TUI exits/interruption loses the working conversation instead of surfacing the pytest/sandbox error and allowing the agent to continue.

y-chell · 2 months ago

Additional reproduction with more focused evidence:

I reproduced this again from the Codex TUI by approving a direct elevated full pytest command:

python -m pytest --basetemp E:\tmp\codex-full-direct-probe -p no:cacheprovider -q

Relevant log sequence:

2026-05-03T16:29:37.810849Z ToolCall: shell_command {"command":"python -m pytest --basetemp E:\\tmp\\codex-full-direct-probe -p no:cacheprovider -q","workdir":"E:\\xiu\\biji\\novels\\opennovel","timeout_ms":120000,"sandbox_permissions":"require_escalated",...}
2026-05-03T16:29:43.482822Z submission_dispatch{otel.name="op.dispatch.exec_approval" ...}: new
2026-05-03T16:29:43.483738Z submission_dispatch{otel.name="op.dispatch.exec_approval" ...}: close
2026-05-03T16:29:47.861631Z MCP server stderr (cmd): [INFO] Received SIGINT, shutting down...
2026-05-03T16:30:09.668699Z thread_spawn: codex_core::session: new

No pytest result or exit code was returned to the conversation. Afterward the next turn logged:

codex_core::context_manager::normalize: Function call output is missing for call id: ...

This is useful because smaller probes behaved differently:

  • A sandboxed minimal pytest using tmp_path failed normally with PermissionError: [WinError 5] Access denied and did not interrupt the session.
  • The same minimal pytest passed when approved/elevated.
  • codex exec with mcp_servers={} and with normal MCP enabled both completed a short python --version command successfully.
  • A direct elevated full pytest from the active TUI is what reproduced the interruption.

So MCP receiving SIGINT appears to be a symptom of the Codex session/task being aborted or restarted, not necessarily the root cause. The failing path seems closer to: Windows TUI + approved/elevated long/full pytest command + missing tool output/session restart.

etraut-openai contributor · 2 months ago

If you're able to repro this, please use /feedback to upload logs and session details, then post the session (thread) ID here.

y-chell · 2 months ago

Broader impact: this is not limited to this Python project. Many Windows development workflows require approved/elevated commands: full test suites, builds, dependency installs, browser/E2E tests, codegen, services, or commands that need access outside the sandbox. If the TUI can abort/restart during an approved command, those projects become hard to continue in Codex CLI. The current workaround would be to bypass sandbox/approvals entirely or run those commands outside Codex, but that defeats the purpose of the approval flow. The approval/escalation path should be reliable and should return command output/errors instead of interrupting the conversation.

y-chell · 2 months ago

The thread ID visible in the local Codex log for the reproduction is:\n\n ext\n019dee80-091c-70b1-9934-43bef820a158\n\n\nThe interruption happened in this same thread around the approved command shown above. I will also use /feedback from the TUI to upload logs/session details if possible.

y-chell · 2 months ago

Feedback has now been uploaded from the Codex TUI.

Uploaded thread:

019dee80-091c-70b1-9934-43bef820a158

y-chell · 2 months ago

Additional clarification after further testing:

This is not isolated to the main agent. I also tried asking a sub-agent from the Codex interactive TUI to run the same full pytest command. The result is the same: the entire Codex CLI TUI exits back to PowerShell.

So delegating the command to a sub-agent does not isolate or avoid the failure. Both main-agent and sub-agent shell tool calls appear to go through the same interactive TUI command execution / approval / child-process handling path, and that shared path is what fails.

I also tested the same full pytest command through codex exec on codex-cli 0.130.0, and it succeeds:

codex exec -C /e/xiu/biji/novels/opennovel -s danger-full-access --skip-git-repo-check "only run: python -m pytest tests -q"

256 passed in 4.00s

The same command also succeeds outside Codex TUI.

So the problem appears specific to the interactive Codex TUI path. The test suite and command are valid; Codex non-interactive exec can run it successfully. The failure is that the interactive TUI exits/interruption occurs when trying to run the full test workflow from the TUI, instead of keeping the session alive and returning stdout/stderr/exit code.

This is especially blocking for real project work because Codex cannot complete the normal coding loop:

  1. edit code
  2. run the full test suite
  3. inspect failures
  4. continue fixing

If the full test command exits the entire TUI, Codex loses the ability to validate and continue from the same conversation.

y-chell · 2 months ago

Update: I found the immediate trigger in my project.

The project used os.kill(pid, 0) as a Unix-style PID liveness check. On Windows, this is not a safe liveness check and can emit a console control event / interrupt the process. In my repro, pytest was effectively interrupted by the project code itself, which explains the KeyboardInterrupt after partial progress.

After replacing that code with a Windows-safe PID check using OpenProcess + GetExitCodeProcess, the same command now completes successfully inside Codex CLI:

python -m pytest tests -q

Result:

264 passed in 4.10s

So the original repro should not be treated as a pure Codex CLI bug.

That said, Claude Code did not terminate under the same project/test scenario, while Codex CLI did. This may still be useful as a Windows compatibility/isolation case: Codex CLI appears more vulnerable to child-process console control events affecting the TUI/session.

y-chell · 2 months ago

One more product-level clarification:

I understand now that the immediate trigger was a project-side Windows compatibility bug (os.kill(pid, 0)), so this should not be treated as a pure Codex bug.

However, the user-facing difference is still important: the same buggy project/test scenario did not terminate Claude Code, while Codex CLI lost/interrupted the interactive session. From a developer workflow perspective, that is a meaningful robustness gap.

Even when a child process or test suite misbehaves, the parent AI coding TUI ideally should isolate the failure, preserve the conversation, and return the command failure/output to the agent. If the whole TUI session is interrupted, the coding loop breaks:

  1. edit code
  2. run tests
  3. inspect failure
  4. continue fixing

This is especially noticeable because Claude Code appears to handle this kind of child-process/console-control failure more gracefully in the same environment. So while the project code was wrong, Codex could still improve its Windows TUI isolation/recovery behavior.

I am sharing this because I want Codex CLI to keep improving and become more robust in real Windows development workflows, especially for the full coding loop where agents need to run tests and continue from failures without losing the session.