openai / openai/codex

[macOS Desktop] functions.exec cell never settles after nested tool completes

Open
#40,777 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

app bug tool-calls
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

Summary

On Codex Desktop for macOS, an outer functions.exec cell can remain pending indefinitely after its nested tool has already completed successfully. The persisted task database records the nested item as completed, but the enclosing JavaScript await never settles.

This is a current macOS reproduction of the post-tool-result stall class previously described in #24738, which the original reporter self-closed.

Environment

  • macOS, Apple Silicon
  • Codex Desktop: 26.818.61809 (build 7019)
  • Primary runtime bundle: 26.819.11345
  • Dynamic tool registry during the live repro: 312 tools
  • The defect reproduced with third-party claude-mem tools absent

Minimal live reproduction

  1. Start a functions.exec cell that sequentially awaits:
    1. nested exec_command running /usr/bin/true
    2. workspace dependency discovery
    3. a GitHub fetch
  2. The outer cell yields after 30 seconds with Script running with cell ID ....
  3. Wait another 60 seconds, then another 120 seconds.
  4. The cell remains pending for more than 211 seconds.
  5. Inspect the task's persisted thread_items row for the first nested call.

Persisted result:

rollout_ordinal: 727
command: /bin/zsh -c /usr/bin/true
status: completed
exit_code: 0
duration_ms: 0

The second and third nested calls are never reached because the first await never settles.

After terminating only the enclosing cell, a fresh nested exec_command querying the database completes in 0.3 seconds. This shows that the shell and tool worker are healthy; the lost signal is between the completed nested item and the enclosing orchestration promise.

Cross-tool evidence

During earlier occurrences in the same task, all of these appeared hung to the outer cell but were persisted as completed:

  • local commands: exit code 0, 0–1092 ms
  • workspace dependency discovery: 22 ms
  • GitHub fetch: 868 ms and 1166 ms
  • context search: 1056 ms

Pure JavaScript inside functions.exec still completed immediately.

Cancellation leak

A controlled test found that terminating an outer cell awaiting nested exec_command("/bin/sleep 15") did not cancel the nested process. pgrep still showed the wrapper and /bin/sleep 15; persisted history later recorded the command completing after 14,868 ms.

Repeated terminate-and-retry therefore leaves nested work behind and may increase bounded-worker or queue pressure.

Desktop log evidence

The same desktop session contains:

mcp_request_timeout ... pendingCount=5 ... timeoutMs=30000

The request later routed successfully at 31.9 seconds. The log also repeatedly records:

Received turn/started for unknown conversation
Received item/started for unknown conversation
Received item/completed for unknown conversation

Those unknown-conversation events referenced another active task, so they are correlation rather than the exact dropped callback. They point toward the conversation/turn/item event-correlation layer during concurrent task restoration.

Expected behavior

  • A completed nested result promptly settles the enclosing functions.exec promise.
  • If forwarding fails, the outer cell surfaces a bounded error rather than pending forever.
  • Terminating the outer cell cancels or safely detaches nested requests and cleans up local children.

Actual behavior

  • Nested item completes and is persisted successfully.
  • Enclosing await never settles.
  • The cell remains pending indefinitely.
  • Termination does not propagate to a still-running nested process.

I can provide additional redacted SQLite queries and timestamp extracts if needed.

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.

Research direction

Start with the functions.exec reproduction using nested exec_command and inspect the persisted thread_items record alongside the desktop conversation and item event logs. Compare completion forwarding with outer-cell termination and verify that completed nested results settle the await, while termination cancels or safely detaches child work without leaving processes behind.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, macos, rust
Domain
desktop, devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.