openai / openai/codex

[macOS/iPhone] Same Codex task shows different active turns and reports stale turn as latest

Open
#44,599 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

app app-server bug remote
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

Summary

The same Codex task can retain multiple non-aborted turns without completion events. Different clients then display different turns as the current one.

In one observed case:

  • the iPhone remote UI displayed an older turn as still running, including an active command indicator;
  • the macOS ChatGPT/Codex UI displayed a newer turn doing unrelated work in the same task;
  • the task-status API reported the older unresolved turn as latestTurn, even though the rollout contained newer turn events;
  • the older command had no corresponding live OS process;
  • the goal badge also differed across clients (blocked on iPhone and stalled on macOS).

This appears to be a turn-lifecycle and client-synchronization defect rather than two intentionally separate tasks.

Environment
  • macOS 27.0
  • ChatGPT desktop 26.903.71938 (build 8576)
  • bundled Codex CLI 0.153.4
  • remote client: ChatGPT/Codex on iPhone
  • one long-running local Codex task with a sustained goal
Sanitized evidence

The local rollout contained:

  • an older user turn with task_started, continued tool activity for approximately 14 minutes, and no task_complete or turn_aborted;
  • a newer user turn started roughly ten hours later in the same task and continued producing current messages;
  • another older goal continuation with task_started and no terminal event;
  • one separate turn that was correctly recorded as turn_aborted.

At inspection time, there were three non-aborted task_started records without matching task_complete events. Only the newest turn appeared to be doing real work.

The app's task snapshot still selected the old turn as:

thread.status = active
latestTurn.status = inProgress
latestTurn = older unresolved turn
latestToolMarker.status = failed

Meanwhile, the macOS UI visibly rendered messages from the newer turn. The iPhone UI remained attached to the older turn and showed its command as running, although no matching command process existed.

The rollout was approximately 158 MiB with about 27,000 records. No private task content or repository data is attached.

Steps that led to the state
  1. Run a long-lived Codex task with a sustained goal on macOS.
  2. Continue the same task remotely from an iPhone.
  3. Allow a turn containing tool execution to become interrupted or otherwise stop producing events without receiving a terminal turn event.
  4. Continue or resume the sustained goal in the same task.
  5. Open the task on both clients.

Observed result: the iPhone and macOS clients can attach to different unresolved turns, and the task API may select the older turn as latest.

Expected behavior
  • A task should have one authoritative current turn.
  • Starting or resuming a newer turn should close, abort, or supersede any older unresolved turn.
  • latestTurn should identify the newest authoritative turn.
  • Desktop and mobile clients should render the same current turn and command state.
  • A command with no live execution should not remain displayed as running.
  • Goal state labels should converge across clients.
  • Automatic goal continuation should not proceed while an earlier turn remains ambiguously in progress.
Impact
  • Users may believe two sessions are running.
  • Remote users can reopen a stale turn and repeat work that already continued elsewhere.
  • Automatic continuations and repeated recovery can consume additional tokens.
  • The UI cannot reliably identify which work is current or safe to stop.

This is potentially related to #34971 because repeated continuation and recovery may amplify token usage in long tasks, but this report concerns the narrower turn-lifecycle and cross-device synchronization failure. It does not claim that an orphaned record alone continues consuming tokens.

For privacy, this report omits screenshots, repository and project names, filesystem paths, machine name, task text, and full task/turn identifiers. Sanitized event shapes or timestamps can be supplied if maintainers need them.

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

No source files or tests are named. Start with the task-status API, turn-lifecycle records, and task snapshot selection described in the report; reproduce the interrupted-turn sequence using sanitized event shapes if needed. Done means one authoritative current turn, consistent desktop and mobile state, no dead command shown as running, and converged goal labels.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
api, distributed-systems
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.