codex - 💡(How to fix) Fix Codex CLI on macOS used `launchctl submit` for child dispatches, causing persistent respawn loops and runaway token usage

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

A Codex CLI orchestration run on macOS dispatched child codex exec workers via launchctl submit instead of a one-shot detached process. That registered launchd-managed jobs which kept re-running the same codex exec "$(cat CODEX_BRIEF.md)" commands from the same worktrees for roughly 14 days, causing large unintended token usage until I manually removed the jobs.

This appears to be an unsafe implementation choice by Codex, not an explicit user request for persistent background jobs.

Error Message

  • ideally detect self-reinvocation / repeated-brief loops and stop or warn

Root Cause

A Codex CLI orchestration run on macOS dispatched child codex exec workers via launchctl submit instead of a one-shot detached process. That registered launchd-managed jobs which kept re-running the same codex exec "$(cat CODEX_BRIEF.md)" commands from the same worktrees for roughly 14 days, causing large unintended token usage until I manually removed the jobs.

This appears to be an unsafe implementation choice by Codex, not an explicit user request for persistent background jobs.

Fix Action

Fix / Workaround

A Codex CLI orchestration run on macOS dispatched child codex exec workers via launchctl submit instead of a one-shot detached process. That registered launchd-managed jobs which kept re-running the same codex exec "$(cat CODEX_BRIEF.md)" commands from the same worktrees for roughly 14 days, causing large unintended token usage until I manually removed the jobs.

The prompt asked Codex to dispatch workers, but it did not ask Codex to install persistent OS-managed background jobs with restart behavior.

  • local session file timestamp: May 6, 2026 10:12:49 PM CDT
  • session metadata shows originator: "codex_exec", source: "exec"
  • prompt told Codex to create worktrees, write CODEX_BRIEF.md, fire 4 headless codex exec dispatches, then exit
  • a few minutes later the same session ran 4 launchctl submit commands for labels like:
    • codex-wave-3-boundary-adapter-fix
    • codex-phase-12-3h-5-spec-amendments
    • codex-phase-12-3f-9-quality-gate-smoke
    • codex-phase-12-3g-7-quality-gate-smoke
RAW_BUFFERClick to expand / collapse

Summary

A Codex CLI orchestration run on macOS dispatched child codex exec workers via launchctl submit instead of a one-shot detached process. That registered launchd-managed jobs which kept re-running the same codex exec "$(cat CODEX_BRIEF.md)" commands from the same worktrees for roughly 14 days, causing large unintended token usage until I manually removed the jobs.

This appears to be an unsafe implementation choice by Codex, not an explicit user request for persistent background jobs.

Environment

  • Codex CLI observed in logs: 0.128.0 through 0.130.0
  • macOS: 26.4 (Apple Silicon)
  • Machine timezone: America/Chicago
  • Usage mode: local codex exec / headless orchestration on macOS

What happened

A parent Codex session received a prompt telling it to:

  • create worktrees
  • write CODEX_BRIEF.md files
  • launch 4 headless Codex workers
  • exit

Instead of using a one-shot detached launch, the parent session used launchctl submit -l <label> -- /bin/bash -lc '... exec codex exec ... "$(cat CODEX_BRIEF.md)" ...' for each worker.

Those labels stayed registered under launchd and the workers kept restarting/re-running the same briefs long after the original task should have finished.

Why this looks like a Codex bug

The prompt asked Codex to dispatch workers, but it did not ask Codex to install persistent OS-managed background jobs with restart behavior.

On macOS, launchctl submit is not a harmless substitute for nohup ... & here. It creates a launchd-managed job. In practice this meant the child jobs persisted and kept coming back, repeatedly consuming tokens without explicit user intent.

Concrete evidence from local session logs

Parent bootstrap session:

  • local session file timestamp: May 6, 2026 10:12:49 PM CDT
  • session metadata shows originator: "codex_exec", source: "exec"
  • prompt told Codex to create worktrees, write CODEX_BRIEF.md, fire 4 headless codex exec dispatches, then exit
  • a few minutes later the same session ran 4 launchctl submit commands for labels like:
    • codex-wave-3-boundary-adapter-fix
    • codex-phase-12-3h-5-spec-amendments
    • codex-phase-12-3f-9-quality-gate-smoke
    • codex-phase-12-3g-7-quality-gate-smoke

One concrete same-lane rerun example on May 20, 2026:

  • a 12.3f.9 lane run started at 6:21:05 PM CDT and completed at 6:22:15 PM CDT
  • the same lane started again at 6:22:16 PM CDT in the same worktree with the same brief

Both runs had originator: "codex_exec", source: "exec", and the same lane prompt injected as the user message.

Scale of impact observed locally

Counting true session starts from the first session_meta line only, I found approximately:

  • wave-3-boundary-adapter: 43,759 starts
  • phase-12-3h-5: 50,845 starts
  • phase-12-3f-9: 20,644 starts
  • phase-12-3g-7: 52,385 starts

Total: 167,633 lane-session starts across the runaway window.

This was the main driver of unexpected token burn on the machine.

Expected behavior

If Codex is asked to dispatch child workers, it should:

  • use a one-shot detached process model unless the user explicitly asks for persistent background jobs
  • never silently install OS-level persistent launchers / service managers without explicit user consent
  • avoid launchctl submit / persistent launchd registration for ordinary worker dispatch
  • clean up any temporary background job registration automatically if it must use OS facilities
  • ideally detect self-reinvocation / repeated-brief loops and stop or warn

Suggested safeguards

  • hard-block or strongly discourage launchctl submit / launchctl bootstrap / similar service-manager registration unless the user explicitly requests persistence
  • add a policy guard around launching codex exec from inside Codex when the launch mechanism is persistent or restart-capable
  • add loop detection when the same worktree + same prompt/brief are being started repeatedly in a short window
  • surface a warning before creating any host-level job that can survive the current interactive session

Notes

I already manually removed the launchctl jobs and killed the live workers, so the immediate runaway is resolved locally. The issue here is the underlying Codex behavior on macOS.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

If Codex is asked to dispatch child workers, it should:

  • use a one-shot detached process model unless the user explicitly asks for persistent background jobs
  • never silently install OS-level persistent launchers / service managers without explicit user consent
  • avoid launchctl submit / persistent launchd registration for ordinary worker dispatch
  • clean up any temporary background job registration automatically if it must use OS facilities
  • ideally detect self-reinvocation / repeated-brief loops and stop or warn

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

codex - 💡(How to fix) Fix Codex CLI on macOS used `launchctl submit` for child dispatches, causing persistent respawn loops and runaway token usage