Skip to content

Codex CLI native process can remain orphaned/headless and spin at 100% CPU after session completes #28794

Open

Description

@mychaelconnolly

Summary

Codex sometimes leaves a stale native codex process running after the session appears complete. In my latest case, the process had no TTY, revoked stdio, an orphaned/reparented process shape, and consumed one full core overnight.

This looks related to #13196 / #12491 / #19753, but the latest incident was not primarily an MCP-helper leak: the hot process was the native Codex CLI child itself.

Environment

  • Codex CLI: 0.140.0
  • macOS: 26.5.1 build 25F80
  • Observed across iTerm2 and Terminal.app usage
  • Frequent use of plan mode / background-terminal style workflows

Observed

On 2026-06-17, my Mac was hot. Process inspection found:

  • parent node PID 17724
  • child native codex PID 17725
  • MCP/lazy-gate children 17767, 17769
  • no TTY
  • fd 0/1 revoked, fd 2 /dev/null
  • process start around 2026-06-16 16:00 local
  • native codex was around 100% CPU
  • accumulated about 831 CPU minutes

The likely matching session log started at 2026-06-16T20:01:41Z and last recorded task_complete at 2026-06-16T22:32:24Z, but the native process was still running hot the next morning.

After terminating only that stale tree, CPU returned to mostly idle.

Expected

When a Codex session/task/terminal lifecycle ends, Codex should terminate or reap its native worker process tree, including MCP/helper descendants, and should not leave a headless codex process spinning under launchd or with revoked stdio.

Actual

A completed/stale Codex process tree remained alive without a usable terminal/stdio path and continued consuming CPU for many hours.

Related

Hypothesis

There is still a session shutdown path where the parent Node/TUI/app process exits or disconnects without terminating the native codex child process group. #19753 appears to address stdio MCP server shutdown, but this case suggests the native Codex worker itself can survive one layer above that fix.

Prior similar local incident

On 2026-05-18, I hit a related but different runaway shape: Codex app-server spawned stale LAN/MCP ping children, each consuming about 96% CPU for over an hour. That issue was mitigated locally by lazy-gating MCP startup, but the 2026-06-17 incident happened at the native Codex worker layer rather than as hot LAN probe children.

Activity

  1. added
    bugSomething isn't working
    CLIIssues related to the Codex CLI
    sessionIssues involving session (thread) management, resuming, forking, naming, archiving
    on Jun 17, 2026
  2. mychaelconnolly commented on Jun 18, 2026

    @mychaelconnolly
    Author

    Reviewed the suggested duplicates.

    #28315 looks like the closest match. It reports a native codex CLI process busy-looping around one full core after its controlling PTY/stdio became invalid, with the hot thread identified as codex-main. This issue is probably in the same failure family.

    I do not think #28352 or #28361 are exact duplicates of this report. They are related lifecycle/process-cleanup leaks, but the leaked or hot processes there are different layers:

    The novel evidence in this issue is narrower and points at the native Codex worker itself rather than only helper processes:

    • Reproduced on macOS with Codex CLI 0.140.0.
    • Hot process was the native codex child, not just MCP, Playwright, Chrome, or other helper descendants.
    • Process had no TTY and revoked stdio shape: fd 0/1 revoked, fd 2 /dev/null.
    • Process tree still had a parent node plus MCP/lazy-gate descendants, so this was not just a detached helper-only leak.
    • Matching session log had already recorded task_complete at 2026-06-16T22:32:24Z, but the native process remained alive and hot the next morning.
    • Native codex accumulated about 831 CPU minutes before killing only that stale tree returned CPU to idle.

    So I would treat this as either a macOS/Node-wrapper variant of #28315, or a follow-up to keep open until shutdown/stdio-invalid handling is confirmed for the native worker layer. If maintainers prefer one tracker, #28315 is the only suggested duplicate I would consider close enough.

  3. mychaelconnolly commented on Jun 21, 2026

    @mychaelconnolly
    Author

    Follow-up recurrence with a different symptom shape.

    On 2026-06-21, I hit another Codex lifecycle/resume failure while using the Claude-side codex@openai-codex plugin (codex-companion.mjs, plugin version 1.0.4) to run a rescue task against a local git checkout.

    This one did not present as an obvious hot orphaned native worker like the original report. Instead, a resumed Codex thread stopped producing output after completing normal read-only shell commands.

    Observed:

    • Job: task-mqnf26ko-fg5mbn
    • Kind: rescue
    • Codex session/thread: 019ee61c-7478-7662-a657-25eefd999f2c
    • Turn: 019ee8e7-da27-7880-b6ff-161ed5862300
    • Start: 2026-06-21T06:39:28.981Z
    • Last useful job update: 2026-06-21T06:39:46.149Z
    • Manual cancel: 2026-06-21T15:15:32.869Z
    • Duration before cancel: about 8h36m
    • Recovery: cancel stuck job, then start a fresh Codex session/thread.

    The important detail: the last observed shell commands were benign read-only inspection commands and completed successfully. The job then produced no verdict/output until manual cancellation.

    Sanitized log excerpt:

    [2026-06-21T06:39:46.100Z] Running command: /bin/zsh -lc "nl -ba <local-repo>/<source-file> | sed -n '<range>'"
    [2026-06-21T06:39:46.100Z] Command completed: /bin/zsh -lc "nl -ba <local-repo>/<source-file> | sed -n '<range>'" (exit 0)
    [2026-06-21T06:39:46.142Z] Running command: /bin/zsh -lc "nl -ba <local-repo>/<test-file> | sed -n '<range>'"
    [2026-06-21T06:39:46.200Z] Command completed: /bin/zsh -lc "nl -ba <local-repo>/<test-file> | sed -n '<range>'" (exit 0)
    [2026-06-21T15:15:32.868Z] Codex turn interrupt failed: no active turn to interrupt
    [2026-06-21T15:15:32.869Z] Cancelled by user.
    

    The companion status path kept reporting the job as running/verifying and later showed the cancelled job as:

    task-mqnf26ko-fg5mbn | cancelled | rescue | Codex Resume
    Duration: 8h 36m
    Codex session ID: 019ee61c-7478-7662-a657-25eefd999f2c
    

    I would separate this from the original high-CPU evidence:

    • Original #28794: native codex worker survived session completion, lost stdio/TTY, and burned CPU.
    • This recurrence: a resumed long-lived Codex session stopped returning a verdict after successful shell reads; status stayed running/verifying until manual cancel; fresh session recovered.

    Possible correlation: this happened on a heavily reused/resumed Codex session after many successful short rescue tasks. It may be a session/resume state-machine stall rather than a terminal/PTY busy-loop.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    CLIIssues related to the Codex CLIbugSomething isn't workingperformancesessionIssues involving session (thread) management, resuming, forking, naming, archiving

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions