Windows Desktop: shell tool timeout does not release agent when a headless Chrome child survives

Open
#35,193 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
48/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Quiet
Tech stack
powershell, rust

Research direction

Start by locating the shell tool timeout implementation and the Windows process-tree cleanup path in the Rust runtime. Reproduce the issue with the provided PowerShell command and headless Chrome workload; done means the tool returns at timeout and the agent is no longer blocked even when child cleanup reports Access denied.

Written by the indexing model from the issue text.

Description

app bug sandbox tool-calls windows-os
Summary

On Codex Desktop for Windows, a shell tool call that starts headless Chrome can remain blocked indefinitely after the declared tool timeout. The agent cannot send updates or run cleanup until the user manually terminates Chrome. Killing the browser process causes the pending tool call to return immediately.

This is not primarily a Chrome screenshot bug: an external child is allowed to hang, but Codex should still regain control at the requested timeout.

Environment
  • Surface: Codex Desktop
  • OS: Windows
  • Shell: PowerShell
  • Workload: local localhost page with a continuously rendered WebGL canvas
  • No network dependency or privileged product mutation involved
Minimal reproduction shape

Run a shell tool with a bounded timeout_ms (for example 35 seconds). The PowerShell command launches chrome.exe --headless=new against a localhost WebGL page and waits for a screenshot artifact. The child does not produce the screenshot and remains alive.

A tracked repro emitted heartbeats at 5, 10, 15, and 20 seconds, then attempted exact-PID-tree cleanup. Cleanup received Access denied. Despite the shell tool declaring a 35-second timeout, the tool call stayed pending for roughly 78 minutes. The agent could not respond during that interval. When the user manually ended Chrome, the tool call returned immediately.

A previous direct chrome.exe --headless --screenshot attempt showed the same class of behavior and left its dedicated profile active for about two hours without producing the PNG.

Expected behavior

At timeout_ms, Codex should:

  1. stop waiting for the shell command;
  2. terminate the full process tree created by that call, ideally using a Windows Job Object;
  3. return a timeout result to the agent even if child cleanup fails;
  4. never require the user to open Task Manager to make the agent responsive again.
Actual behavior
  • The child process tree survives the deadline.
  • Sandbox cleanup can fail with Access denied.
  • The pending shell tool call keeps the whole agent turn blocked.
  • No commentary/heartbeat or alternative tool call is possible.
  • Manual termination of Chrome is what releases the agent.
Additional Windows clue

In the same Codex shell environment, PowerShell Start-Process and even enumeration of Env: can fail with:

Item has already been added. Key in dictionary: 'Path' Key being added: 'PATH'

This suggests the host exposes case-variant environment keys which PowerShell copies into a case-insensitive dictionary. This is a separate spawn-path defect, but it complicates safe background-process/watchdog workarounds.

Suggested fix
  • Put every shell tool invocation in a Windows Job Object owned by the tool runtime and close/terminate that job at timeout.
  • Make timeout return control independently of in-sandbox cleanup success.
  • Normalize case-insensitive environment keys before constructing a PowerShell child environment.
  • Surface process-tree and cleanup status in the tool result.
Local mitigation

The affected workflow now avoids synchronous external Chrome CLI capture entirely and uses an already-connected browser/canvas export path. That prevents recurrence locally but does not address the Codex runtime issue.

Dominant language
Rust
Stars
125k
Forks
19.5k
Avg merge
1m
Merged PRs (30d)
1k

Contributor guide

Open the contributing guide

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.

More from openai/codex

All issues in openai/codex

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.