codex exec stalls in mounted workspace before any writes; no turn.completed across 0.110.0-0.112.0

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

Summary

codex exec stalls during a real Spiderweb-mounted workspace flow before it writes any deliverables.

Across the repro cases below, Codex never reaches turn.completed, never emits the final write step, and never creates the expected game files under the writable mounted workspace.

Public Repro Bundle

I published the full artifact bundle on a public fork branch so the exact prompts, JSON event logs, summaries, and mounted metadata are all inspectable:

Scenario

  • Linux host installs Spiderweb with the repo-local installer.
  • Spiderweb starts with a separate runtime root.
  • A clean local spiderweb-fs-node is mounted at /nodes/local/fs.
  • A second standalone node is mounted at /shared_data.
  • Codex runs via codex exec against the mounted workspace with --skip-git-repo-check, --dangerously-bypass-approvals-and-sandbox, --ephemeral, and --json.
  • The prompt asks Codex to read mounted metadata, consume the shared seed files, and generate game.py, game_manifest.json, walkthrough.txt, and README.md under /nodes/local/fs.

Expected

  • Codex completes the turn.
  • Codex writes the deliverables into the writable mounted workspace.
  • The validator passes.

Actual

  • Codex emits some early discovery/progress events, then stops.
  • No case reaches turn.completed.
  • No case creates the required game files in the writable mounted workspace.

Repro Matrix

| Case | Version | PTY | Exit | Handoff | Stall | Last Event | Last Item |
| --- | --- | --- | --- | --- | --- | --- | --- |
| v0.110.0-json-no-pty | 0.110.0 | no | 1 | codex_idle_after_90s | after_agent_message | item.completed | agent_message |
| v0.111.0-json-no-pty | 0.111.0 | no | 1 | codex_timeout_after_210s | after_tool_result | item.completed | command_execution |
| v0.111.0-json-pty | 0.111.0 | yes | 1 | codex_timeout_after_210s | after_agent_message | item.completed | agent_message |
| v0.112.0-json-no-pty | 0.112.0 | no | 1 | codex_idle_after_90s | after_agent_message | item.started | agent_message |

Shared Invariants

  • All included cases stop before any final write step is visible in the JSON event stream.
  • The writable mounted project tree stays at the seeded state only.
  • The failure is not limited to a single Codex CLI version.
  • PTY wrapping changes the visible stopping point, but does not fix the problem.

Notes

  • This does not look like an approval prompt.
  • In the captured runs, Codex either stops immediately after a completed tool result or after an agent message announcing the upcoming write step.
  • The bundle includes the raw codex.stdout.log JSONL event streams, per-case summaries, prompts, and mounted metadata snapshots.

View original on GitHub ↗

3 Comments

github-actions[bot] contributor · 5 months ago

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

  • #14115
  • #13987
  • #13479

Powered by Codex Action

DeanoC · 5 months ago

I dug deeper with a Spiderweb-mounted live repro and the apparent "stall" is more nuanced than the initial report suggested.

What I found:

  • codex exec --json can go quiet for a long stretch while the turn is still active and making progress internally.
  • In our harness, that silence was being misclassified as a hang because we were enforcing an idle timeout on visible JSON/file events.
  • A longer traced run completed successfully end to end once I raised the total timeout and disabled the idle cutoff.

There is still a Codex-side UX/instrumentation gap though:

  • the core event stream does emit generic ItemStarted/ItemCompleted reasoning lifecycle events during these silent stretches
  • but codex exec --json currently drops those generic reasoning item events, so automation sees no progress and has to guess whether the run is hung or just thinking

I pushed a small investigation patch on my fork that forwards those generic reasoning events into the JSONL output for exec:

  • fork branch: DeanoC/codex branch spiderweb-exec-stall-investigation
  • commit: 8c304a19f (Emit generic reasoning events in exec JSON output)

This is not a PR yet; your contributing guide says external PRs are by invitation only, so I’m just sharing the branch/commit for reference.

I also verified the patch locally with focused tests and a real Spiderweb-mounted run:

  • new tests pass in cargo test -p codex-exec event_processor_with_jsonl_output
  • the patched binary now emits item.started/item.completed JSON events of type reasoning

So the operator-facing fix on our side is: do not treat lack of JSON/file churn as a failure by default.
The Codex-side improvement would be: surface generic reasoning lifecycle events in exec --json so automation can distinguish “still thinking” from “actually wedged”.

DeanoC · 5 months ago

Follow-up from the Spiderweb external-agent E2E work.

Current state on our side:

  • The strict Spiderweb source-backed run is green end-to-end (reliability_ok=true, workspace_bootstrap_ok=true, machine_independence_ok=true).
  • We published a public Spiderweb release (v0.3.1) and are now validating the release-backed path as the real fresh-user install path.

Two Codex-relevant findings from the latest round:

  1. GIT_CEILING_DIRECTORIES mattered in practice.

We carried a small fork-side change to stop ancestor .git walking at GIT_CEILING_DIRECTORIES, which removed host repo climb/noise in our attached-workspace runs.

Fork commit:

  • 3f99d3f69 on branch spiderweb-exec-stall-investigation
  1. The shell/path model is still a meaningful interoperability edge.

In our release-backed validation, tool commands may still start from a shell view where the attached namespace is reachable under a discovered mount root instead of literal /meta / /shared_data. When that happens, Codex can recover if the prompt teaches a one-time namespace_root fallback, but without that it tends to treat /meta/... and /shared_data/... as literal host-root paths and fails the first read/validator steps.

So the remaining upstream-relevant takeaway is:

  • honoring environment/path isolation signals like GIT_CEILING_DIRECTORIES helped a lot
  • shell/tool execution still benefits from stronger respect for the caller's intended namespace/path model, especially in exec flows

I’m not opening a PR because the repo’s contribution policy says external PRs are invitation-only, but I wanted to close the loop with the final findings and the fork commit in case it’s useful.