openai / openai/codex

[macOS Desktop] Unified thread catalog retains deleted cloud chats and missing local rollouts

Open
#42,628 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

app bug session
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

What version of the Codex App are you using (From “About Codex” dialog)?

ChatGPT Desktop / Codex 26.901.22334, build 7746, bundle identifier com.openai.codex.
Bundled CLI: codex-cli 0.153.0.

What subscription do you have?

Signed in with a ChatGPT account; subscription tier omitted.

What platform is your computer?
Darwin 27.0.0 arm64 arm
macOS 27.0 (26A5425a), Apple Silicon
What issue are you seeing?

The desktop sidebar retains ghost entries after their source objects disappear. This has occurred repeatedly with both web-deleted ChatGPT conversations and local Codex rollouts removed from disk. Opening the entries produces errors, and subsequent UI removal attempts also fail.

The additional evidence in this report is the shared local_thread_catalog persistence path, its missing_candidate state, and the relationship to incremental versus full reconciliation. Related cloud-conversation reports are #39897 and #41987; #29868 describes related local-thread symptoms. Please merge or cross-reference this report with the appropriate tracking issue as needed.

Observed cloud-chat logs

These are shortened excerpts from actual incidents; IDs and personal data are redacted. Timestamps are UTC.

2026-09-02T08:45:14.189Z
chatgpt_conversation_update_ignored
conversationId=<cloud-chat-id>
reason=conversation_not_loaded updateType=refetch

2026-09-02T08:55:30.540Z
sa_server_request_failed
method=delete routePattern=/conversation/id/{conversation_id}
status=404 errorCode=conversation_deleted
can_retry=false

The entry remained in the local catalog and sidebar after the backend reported that the conversation had been deleted.

Observed local-rollout logs
2026-09-03T22:01:46.470Z
method=thread/resume source=thread_hydration
failureReason=rollout_not_found
error.code=-32600
error.message="failed to resolve rollout path <redacted>: file does not exist"

2026-09-03T22:03:42.611Z
method=thread/turns/list
error.code=-32600
error.message="invalid paginated history lineage for <local-thread-id>: missing source rollout"
What steps can reproduce the bug?

These sequences describe the reported incidents. Reproduction should use disposable test conversations/tasks.

A. Web-deleted ChatGPT conversation

  1. Have a ChatGPT conversation indexed in the desktop sidebar.
  2. Keep a different conversation active in the desktop renderer.
  3. Delete the indexed conversation on the web.
  4. Observe the stale desktop sidebar entry. In the recorded incident, the desktop logged an ignored refetch update with reason=conversation_not_loaded.
  5. Open the stale entry or try deleting it from the desktop sidebar.
  6. Observe 404 conversation_deleted and continued presence of the entry.
  7. Fully quit and relaunch the app; the stale catalog entry can persist.

B. Externally removed local rollout

  1. Have a disposable local Codex task indexed in the desktop sidebar.
  2. Remove its corresponding rollout JSONL externally from ~/.codex/sessions/....
  3. Open the indexed task in the desktop app.
  4. Observe the missing-rollout errors and the retained sidebar entry.
  5. Attempt to remove the stale entry through the UI and observe the failure.

The local sequence deliberately exercises recovery from external source removal. The cloud sequence occurs through normal web deletion.

What is the expected behavior?
  • A backend conversation_deleted response should invalidate the stale cloud entry and make subsequent UI removal succeed idempotently.
  • For local missing rollouts, verify permanent source absence, distinguish transient unavailability, and offer removal of the stale catalog entry independently of successful history hydration.
  • Reconciliation should eventually detect source deletions after initial indexing and update the sidebar.
  • A repair/rebuild-index action would provide a safe recovery path.
Additional information

Observed local state

  • The affected entries persisted in ~/.codex/sqlite/codex-dev.db, table local_thread_catalog.
  • Fresh ghost entries were still marked missing_candidate=0.
  • Older stale entries were marked missing_candidate=1 and hidden from the sidebar while their catalog records remained.
  • The most recent full-reconciliation timestamps observed were September 3 at 14:34:40 for local tasks and 14:38:38 for ChatGPT conversations, Asia/Shanghai time. Subsequent restarts advanced incremental state while these full-reconciliation timestamps stayed unchanged.
  • PRAGMA integrity_check returned ok.

Investigation hypothesis

The catalog appears to retain stale rows when source deletion is missed by the event/invalidation path. Incremental discovery can continue successfully while retaining rows for deleted sources. The ignored cloud update and stale full-reconciliation timestamp are investigative leads; maintainers should confirm the exact control flow and intended reconciliation schedule.

Workaround and diagnostic caveat

After collecting evidence, confirmed stale catalog rows were manually removed and catalog_revision was incremented. This cleared the targeted ghost entries. One obsolete automation-run row associated with an absent local rollout was also removed; the automation configuration was retained. Integrity checks stayed ok. The issue preceded these manual database changes, and the affected entries have now been cleaned up locally. Manual database repair should remain a specialist recovery procedure with verified source absence; the product needs a supported self-healing path.

The public report contains shortened log excerpts, redacted IDs, and generic local paths. Full IDs and narrowly scoped logs can be provided through private OpenAI Support.

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

Start by tracing the shared local_thread_catalog persistence path and the incremental versus full reconciliation behavior described in the report. Reproduce both the web-deleted conversation and externally removed local rollout with disposable data, then inspect the logged conversation_deleted, missing_candidate, and rollout_not_found paths. Done means source deletions are reconciled, stale entries can be removed independently of hydration, and transient absence is not treated as permanent.

Written by the indexing model from the issue text.

Assessment

Tech stack
macos, rust, sqlite
Domain
databases, desktop
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.