Repository navigation
Codex task shows only the first turn after reopening because thread history projection is stuck before task_complete #42662
Description
What version of Codex CLI is running?
- Codex CLI: `0.145.0
What subscription do you have?
plus
Which model were you using?
gpt 5.6 sol
What platform is your computer?
Linux x86_64 x86_64
What terminal emulator and version are you using (if applicable)?
Codex Desktop integrated terminal connected to an Ubuntu 22.04 remote host over Remote SSH. Shell: Bash (/bin/bash). TERM=dumb. No screen, tmux, or zellij multiplexer was in use. Codex Desktop app version is unavailable from the remote CLI.
Codex doctor report
{
"schemaVersion": 1,
"generatedAt": "1788490320s since unix epoch",
"overallStatus": "fail",
"codexVersion": "0.145.0",
"checks": {
"app_server.status": {
"id": "app_server.status",
"category": "app-server",
"status": "warning",
"summary": "background server socket is stale or unreachable",
"details": {
"app-server version": "unavailable (failed to connect to control socket)",
"control socket": "/root/.codex/app-server-control/app-server-control.sock",
"daemon state dir": "/root/.codex/app-server-daemon",
"mode": "ephemeral",
"pid file": "/root/.codex/app-server-daemon/app-server.pid (missing)",
"settings": "/root/.codex/app-server-daemon/settings.json (missing)",
"status": "stale or unreachable",
"update-loop pid file": "/root/.codex/app-server-daemon/app-server-updater.pid (missing)"
},
"remediation": "Run codex app-server daemon version for more details.",
"durationMs": 0
},
"auth.credentials": {
"id": "auth.credentials",
"category": "auth",
"status": "ok",
"summary": "auth is configured",
"details": {
"auth file": "/root/.codex/auth.json",
"auth storage mode": "File",
"stored API key": "false",
"stored ChatGPT tokens": "true",
"stored agent identity": "false",
"stored auth mode": "chatgpt"
},
"remediation": null,
"durationMs": 0
},
"config.load": {
"id": "config.load",
"category": "config",
"status": "ok",
"summary": "config loaded",
"details": {
"CODEX_HOME": "/root/.codex",
"config.toml": "/root/.codex/config.toml",
"config.toml parse": "ok",
"cwd": "/data/SkillEmpirical",
"model": "gpt-5.6-sol",
"model provider": "openai",
"sqlite home": "/root/.codex"
},
"remediation": null,
"durationMs": 0
},
"git.environment": {
"id": "git.environment",
"category": "git",
"status": "ok",
"summary": "git version 2.34.1",
"details": {
"repo detected": "true",
"repo root": "/data/SkillEmpirical",
"selected git": "/usr/bin/git",
"git version": "git version 2.34.1"
},
"remediation": null,
"durationMs": 113
},
"installation": {
"id": "installation",
"category": "install",
"status": "ok",
"summary": "installation looks consistent",
"details": {
"managed by npm": "true",
"managed by bun": "false",
"managed by pnpm": "false",
"managed package root": "/usr/lib/node_modules/@openai/codex",
"npm update target": "/usr/lib/node_modules/@openai/codex"
},
"remediation": null,
"durationMs": 151
},
"network.provider_reachability": {
"id": "network.provider_reachability",
"category": "reachability",
"status": "fail",
"summary": "one or more required provider endpoints are unreachable over HTTP",
"details": {
"ChatGPT base URL": "https://chatgpt.com/backend-api/ connect failed (required)",
"reachability mode": "ChatGPT auth"
},
"remediation": "Check proxy, VPN, firewall, DNS, and custom CA configuration.",
"durationMs": 37
},
"network.websocket_reachability": {
"id": "network.websocket_reachability",
"category": "websocket",
"status": "warning",
"summary": "Responses WebSocket failed; HTTPS fallback may still work",
"details": {
"DNS": "lookup failed (Operation not permitted (os error 1))",
"auth mode": "chatgpt",
"connect timeout": "15000 ms",
"handshake transport error": "network error: Operation not permitted (os error 1)",
"model provider": "openai",
"provider name": "OpenAI",
"supports websockets": "true",
"wire API": "responses"
},
"remediation": "Check proxy, VPN, firewall, DNS, custom CA, and WebSocket policy support.",
"durationMs": 140
},
"runtime.provenance": {
"id": "runtime.provenance",
"category": "runtime",
"status": "ok",
"summary": "running npm on linux-x86_64",
"details": {
"commit": "unknown",
"install method": "npm",
"platform": "linux-x86_64",
"version": "0.145.0"
},
"remediation": null,
"durationMs": 0
},
"state.paths": {
"id": "state.paths",
"category": "state",
"status": "ok",
"summary": "state paths and databases are inspectable",
"details": {
"CODEX_HOME": "/root/.codex (dir)",
"state DB": "/root/.codex/state_5.sqlite (file)",
"state DB integrity": "ok",
"thread history DB": "/root/.codex/thread_history_1.sqlite (file)",
"thread history DB integrity": "ok",
"log DB": "/root/.codex/logs_2.sqlite (file)",
"log DB integrity": "ok"
},
"remediation": null,
"durationMs": 1518
},
"state.rollout_db_parity": {
"id": "state.rollout_db_parity",
"category": "threads",
"status": "ok",
"summary": "rollout files and state DB thread inventory agree",
"details": {
"rollout DB active files": "72",
"rollout DB active rows": "72",
"rollout DB archived files": "10",
"rollout DB archived rows": "10",
"rollout DB duplicate rollout thread ids": "0",
"rollout DB missing active rows": "0",
"rollout DB missing archived rows": "0",
"rollout DB scan errors": "0",
"rollout DB sources": "exec=37, vscode=29, subagent:other=16",
"rollout DB stale rows": "0"
},
"remediation": null,
"durationMs": 145
},
"system.environment": {
"id": "system.environment",
"category": "system",
"status": "ok",
"summary": "OS language C",
"details": {
"LANG": "en_US.UTF-8",
"LC_ALL": "C.UTF-8",
"os": "Ubuntu 22.4.0 (jammy) [64-bit]",
"os type": "Ubuntu",
"os version": "22.4.0"
},
"remediation": null,
"durationMs": 30
},
"terminal.env": {
"id": "terminal.env",
"category": "terminal",
"status": "fail",
"summary": "TERM=dumb - colors and cursor control are disabled",
"details": {
"SSH_CLIENT": "present",
"SSH_CONNECTION": "present",
"TERM": "dumb",
"stderr is terminal": "false",
"stdin is terminal": "false",
"stdout is terminal": "false",
"terminal size": "80x24"
},
"remediation": null,
"durationMs": 13
}
}
}What issue are you seeing?
A multi-turn Codex task on a remote SSH host displayed only its first conversation turn after the task was closed and reopened.
The later turns were not deleted. They were still present in the rollout JSONL, and Codex could continue using their context. However, the Codex UI and task-history API returned only the first turn and incorrectly marked it as inProgress.
Affected thread ID:
01a0609d-f30e-7f21-aa14-89e24a45e114
The raw rollout contained five completed turns, with valid task_started and task_complete events. However, thread_history_1.sqlite initially contained only one projected turn and two projected message items.
The projection cursor was stuck immediately before the first valid task_complete event:
thread_history_projection_state.next_rollout_byte_offset = 91671
thread_history_projection_state.next_rollout_ordinal = 10
The logs repeatedly reported:
codex_thread_store::local::thread_history_materialization
skipping rejected rollout line while projecting: invalid type: map, expected f64
Renaming the task updated its title and sidebar recency but did not rebuild the missing history.
As a local recovery workaround, I backed up the SQLite database and reconstructed this thread's thread_turns and thread_items projection rows from the intact rollout JSONL. After the projection refreshed, all five completed turns became visible again.
The rollout JSONL itself was never modified.
What steps can reproduce the bug?
- Connect the Codex desktop app to an Ubuntu workspace using Remote SSH.
- Create a Codex task and complete the first user/assistant turn.
- Leave or close the task.
- Reopen the same task later.
- Continue the task for several additional turns.
- Close and reopen the task again.
- Observe that only the first turn is displayed.
- Inspect the rollout JSONL and confirm that all later turns and
task_completeevents are still present. - Inspect
thread_history_1.sqliteand observe that the history projection has stopped before the firsttask_complete.
Affected thread ID:
01a0609d-f30e-7f21-aa14-89e24a45e114
What is the expected behavior?
All completed conversation turns stored in the rollout JSONL should be restored and displayed when the task is reopened.
A completed turn must not remain marked as inProgress.
If the history projector encounters an incompatible or unrecognized event field, it should either migrate or safely skip that field without preventing all subsequent valid turns from being projected.
Codex should also provide a supported command or UI action to rebuild a task's history projection from its rollout JSONL.
Additional information
Environment:
- Codex CLI: 0.145.0
- Model: gpt-5.6-sol
- Host OS: Ubuntu 22.04, Linux x86_64
- Connection: Codex desktop app connected through Remote SSH
- Thread source recorded in state database: vscode
- History mode: paginated
- Workspace: /data/SkillEmpirical
- Affected thread ID: 01a0609d-f30e-7f21-aa14-89e24a45e114
The affected rollout JSONL was valid newline-delimited JSON with contiguous event ordinals.
At diagnosis, it contained five complete task boundaries, ending at ordinals 11, 46, 169, 198, and 260. The task-history API nevertheless returned one turn, marked inProgress, with hasMore=false.
The same projection database contained only one inProgress turn for each of three local Codex threads, which may indicate a broader projection or migration problem.
Impact:
- Users may incorrectly believe their conversation history has been deleted.
- Completed analysis and decisions become inaccessible through the UI.
- New turns can continue to be appended while the visible history remains stuck.
- There is no documented recovery or reindex command.
Requested fixes:
- Make the history projector tolerate or migrate incompatible rollout field variants.
- Safely advance past non-history events that cannot be decoded.
- Correctly reconcile
task_completeevents. - Add a supported history rebuild/reindex command.
- Display a warning when the projection cursor falls behind the rollout file.
I can provide the rollout JSONL, relevant SQLite rows, and log records privately after redaction. I am not attaching the raw rollout publicly because it contains prompts, local file paths, and command output.
Activity
github-actions commentedon Sep 4, 2026
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
84dnnvbdvp-debug commentedon Sep 4, 2026
The failure shape here looks version-specific rather than like lost canonical history.
In
rust-v0.145.0, the projector logs and drops a rollout line that failsRolloutLinedeserialization, but the subsequent transactional projection still requires exact ordinal continuity. That means one rejected record can make the transaction abort and leavethread_history_projection_stateat the old byte/ordinal checkpoint even while the JSONL keeps growing.The recovery behavior changed immediately after 0.146.0: #36083 adjusted rollout deserialization, and #36188 made rejected/unknown lines and skipped ordinal ranges advance the byte and ordinal checkpoints together. I verified that
rust-v0.147.0contains that machinery, and currentrust-v0.153.2still reads from the persistednext_byte_offset/next_ordinaland applies the same deferred-rejected-line / skipped-range recovery path.So a useful discriminator should be: upgrade this same host from 0.145.0 to at least 0.147.0 (ideally current 0.153.2), reopen the same affected thread once, then rerun the two projection-state/history queries. Because the 0.145 failure rolls the transaction back, the checkpoint should still be before the rejected suffix; the newer projector should reread that suffix and catch up without manual SQLite surgery. If it remains stuck on 0.153.2, the new projector warning plus unchanged byte/ordinal checkpoint would establish a current regression rather than this older fixed path.
The duplicate-ordinal reports the bot linked (for example #41657/#42157) are a related projection-stall class, but their observed corrupting record is different: a valid record reuses an ordinal. Here the
invalid type: map, expected f64warning is direct evidence of the older rejected-record path.gudelian11111 commentedon Sep 4, 2026
log1011z commentedon Sep 5, 2026
A possible cause is that the CLI and the background app server are running different versions.
You can check their versions with:
The
cliVersionandappServerVersionshould match, and the app server should not still be running0.145.0.If the versions do not match, restarting the app server may resolve the issue.
This worked for me. After restarting the app server, I created a new conversation thread, had multiple turns in it, closed and reopened the thread, and the complete conversation history was displayed correctly.
gudelian11111 commentedon Sep 7, 2026
Thanks for the suggestion. I checked, and both versions now match:
cliVersion: 0.153.2
appServerVersion: 0.153.2
The app server is no longer running 0.145.0. However, the issue still persists—even after restarting the app server and creating a new conversation with multiple turns, reopening the thread does not display the complete conversation history.
yoshichiha commentedon Sep 9, 2026
I can confirm the same failure shape on macOS, including for tasks initiated through ChatGPT mobile Remote.
Environment:
26.727.51351The mobile-originated tasks were confirmed to execute locally on the paired Mac. For one affected task, the rollout JSONL contained 31 events, while
thread_history_1.sqlitecontained only 4 correspondingthread_items. The associatedthread_turnsrow remainedinProgresswithcompleted_at = NULL, even though the complete event sequence remained in the rollout.As a result, the conversation was absent or incomplete in the desktop UI despite the canonical rollout being intact. This suggests the projection problem also affects locally executed mobile Remote tasks, not only Remote SSH threads.
I can provide redacted projection rows and log excerpts privately. Raw logs are not attached because they contain prompts and local paths.
vbzgn2rc98-ctrl commentedon Sep 11, 2026
I can reproduce this on Windows local, without Remote SSH, using Codex desktop app 26.903.9818.0.
A persistent goal kept one task turn marked
inProgressfor 22h 18m 53s. The task continued through many tool calls and context compactions, and local checkpoint artifacts confirm that substantial later work existed. However, both the Windows desktop app and mobile Remote rendered only an older section from the first day.Task-history readback still exposed the old turn as
inProgressinstead of presenting the later activity as accessible history, even though the task's update timestamp advanced and work continued.I then completed the persistent goal to force the long-running turn to close. Completing or removing the goal did not unstick UI rendering: later context remained missing, and newly added context continued to be swallowed on both desktop and mobile Remote.
Expected behavior: very long running turns should remain fully accessible through paging or safe segmentation. Reopening a task—or completing/removing its goal—must not strand later messages and tool results behind a stale
inProgresshistory projection.I can provide redacted diagnostics privately. I am not posting the raw rollout, thread ID, screenshots, local paths, or logs because they contain private data.
diegocantarero commentedon Sep 12, 2026
Related projection symptom (sanitized, observed 2026-09-11/12 UTC): multiple Remote tasks can show a current task index but an incomplete or stale conversation after the desktop turn has finished. Local inspection found terminal turns reported as completed with error=null but an empty projected item list, while the host-side rollout/checkpoint still contained the turn. The same pattern was observed across more than one host. Tracking and fuller reproduction are in #28340; related mobile hydration report is #41377. Please reconcile task completion with the canonical message projection and make the mobile cursor/revision recoverable after a sequence gap.
shivamtawari commentedon Sep 18, 2026
Confirmed recovery on Codex Desktop over Remote SSH.
Our rollout JSONL was intact, but thread_history_1.sqlite was stuck at next_rollout_ordinal = 13, with only 1 turn and 3 items projected. The parser error was:
invalid type: map, expected f64Upgrading the CLI to 0.155.1 alone wasn’t enough: codex app-server daemon version still reported the running app-server as 0.146.0. Even closing/reopening Desktop left that long-lived remote process running.
What worked:
After reopening the thread, the projection rebuilt to 6 turns, 68 items, and next_rollout_ordinal = 221. The full history is readable again.
We used both a targeted projection reset and an actual remote app-server restart, so we haven’t established whether restarting the upgraded server alone would have sufficed. Try the restart first; database repair should be backed up and strictly thread-scoped.