Nested codex exec commands inherit parent CODEX_THREAD_ID instead of nested thread id

Resolved 💬 2 comments Opened Mar 23, 2026 by aquiles-ai123 Closed Apr 7, 2026
💡 Likely answer: A maintainer (etraut-openai, contributor) responded on this thread — see the highlighted reply below.

Nested codex exec commands inherit the parent CODEX_THREAD_ID instead of the nested thread id

Summary

When codex exec is launched from inside an existing Codex session, the nested session gets its own thread.started.thread_id, but commands executed by that nested session still see the parent CODEX_THREAD_ID in their environment.

This looks like environment leakage from the outer Codex process into nested Codex command executions.

Why this matters

Any script, hook, or command that relies on CODEX_THREAD_ID for correlation, logging, or per-thread state will attribute work to the wrong thread.

Environment

  • Codex CLI: codex-cli 0.116.0
  • Outer shell environment includes:
CODEX_THREAD_ID=019d1afb-b2c7-72d3-b240-f3ee9d31b2c9

Repro

This repro is intended to be run from inside an existing Codex session.

Read-only example

codex exec --ephemeral --skip-git-repo-check --color never --json   -s read-only -C /home/cryptotrading74   'Run env | sort | rg "^CODEX_THREAD_ID=" and stop.'   > /tmp/codex_threadid_mismatch.jsonl

Observed transcript:

{"type":"thread.started","thread_id":"019d1be2-5752-7553-80c4-66e6dbddb174"}
{"type":"item.completed","item":{"type":"command_execution","aggregated_output":"CODEX_THREAD_ID=019d1afb-b2c7-72d3-b240-f3ee9d31b2c9\n","exit_code":0,"status":"completed"}}

Workspace-write example

codex exec --ephemeral --skip-git-repo-check --color never --json   -s workspace-write -C /home/cryptotrading74   'Run env | sort | rg "^CODEX_THREAD_ID=" and stop.'   > /tmp/codex_threadid_mismatch_ws.jsonl

Observed transcript:

{"type":"thread.started","thread_id":"019d1be2-fe81-74b3-8809-3cc1f9c8f3a8"}
{"type":"item.completed","item":{"type":"command_execution","aggregated_output":"CODEX_THREAD_ID=019d1afb-b2c7-72d3-b240-f3ee9d31b2c9\n","exit_code":0,"status":"completed"}}

Expected behavior

Commands executed by a nested codex exec session should see the nested session's thread id, or CODEX_THREAD_ID should be unset if that variable is not meant to be inherited.

Actual behavior

Commands see the parent session's CODEX_THREAD_ID, even though the nested session has a different thread.started.thread_id.

Files / artifacts

  • /tmp/codex_threadid_mismatch.jsonl
  • /tmp/codex_threadid_mismatch_ws.jsonl

Suggested title

Nested codex exec commands inherit parent CODEX_THREAD_ID instead of nested thread id

View original on GitHub ↗

2 Comments

etraut-openai contributor · 4 months ago

Thanks for the bug report. This will be addressed in the next release.

rxdt · 2 months ago

Turns out it's not a bug it's a feature? You only unset the env vars for the agent's env.

Try this, it successfully creates a sub-agent (don't pass agent-type, model, or reasoning effort)
env -u CODEX_THREAD_ID -u CODEX_CONVERSATION_ID -u CODEX_SESSION_ID codex exec...

> env -u CODEX_THREAD_ID -u CODEX_CONVERSATION_ID -u CODEX_SESSION_ID codex exec --json --sandbox "Spawn a subagent to make specs/orchestrate.md agent-optimized. Meanwhile you add a Mermaid diagram to README.md. Report on subagent's status frequently."
{"type":"thread.started","thread_id":"
...
- [README.md](/Users/rxdt/ai_deployment_calculator/README.md): added a compact Mermaid `Flow` diagram.\n- [specs/orchestrate.md](/Users/rxdt/ai_deployment_calculator/specs/orchestrate.md): subagent Arendt created an agent-optimized orchestration spec.\n\nSubagent status:\n- Completed.\n- Changed only `specs/orchestrate.md`.\n- Verified at 61 lines.\n- No tests run, doc-only change.\n\nLocal check:\n- `README.md` is 77 lines.\n- `git status --short` shows `M README.md` and `?? specs/orchestrate.md`."}}

I check git status and both files are indeed there.