Skip to content

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

Closed

Description

@Jerry2003sky

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.

Activity

  1. added
    bugSomething isn't working
    appIssues related to the Codex desktop app
    sessionIssues involving session (thread) management, resuming, forking, naming, archiving
    on Sep 3, 2026
  2. Collapsar0615 commented on Sep 8, 2026

    @Collapsar0615

    Recurring on ChatGPT Desktop / Codex 26.901.41123 (build 7942), bundle com.openai.codex, macOS 26.6.2, Apple Silicon (arm64). This is the second confirmed incident on this Mac, after a previous targeted cache cleanup.

    Reproduction and recurrence

    1. Have ordinary ChatGPT conversations indexed in the Mac desktop sidebar.
    2. Delete some of those conversations in the iPhone ChatGPT app.
    3. The deleted conversations disappear from the fresh, authenticated ChatGPT web sidebar, but remain under Recents on the Mac.
    4. The local catalog retains the missing conversations as visible entries.

    The latest incident was observed on September 7, 2026 (America/New_York); diagnostics and cleanup ran around September 8, 00:05 UTC. The first confirmed cleanup was September 2.

    Verified local evidence

    The saved database backups from both incidents were re-read to confirm the counts:

    Observation First incident, Sep 2 Second incident, Sep 7/8
    Ordinary chats in the freshly checked web sidebar 9 9
    Ordinary rows in the affected local host catalog 19 16
    Rows marked missing_candidate=0 9 14
    Rows marked missing_candidate=1 10 2

    In the second incident, five source-missing conversations were still marked missing_candidate=0 and appeared in the Mac screenshot. Another two obsolete entries were already marked missing. The relevant table is local_thread_catalog in ~/.codex/sqlite/codex-dev.db.

    Immediately before the second repair, the affected ChatGPT host had:

    • initial_build_complete=1
    • observation_sequence=487
    • last_full_reconciled_at=2026-09-06T01:30:17.757Z

    Recovery performed and limitations

    After read-only comparison with the fresh cloud list and a recoverable SQLite backup, only the seven verified source-missing ordinary-chat catalog rows were removed. The cleanup was restricted to the affected host and exact conversation IDs, with project_id IS NULL. The catalog revision advanced from 524 to 525.

    Afterward, the nine remaining ordinary-chat IDs matched the web sidebar exactly, and PRAGMA quick_check returned ok. All 205 project-chat rows, three local Codex task rows, and two other-host rows were verified unchanged within the transaction. A subsequent normal local catalog update advanced the revision again.

    This recovered the local index, but the recurrence after the first cleanup demonstrates that manual cache repair is only a workaround. A direct ID comparison of both saved repair datasets also confirmed zero overlap: all seven candidates in the second incident were different from the ten removed in the first cleanup. This is newly accumulated stale state, rather than the previously removed rows reappearing. The app bundle was inspected read-only and was not patched.

    Investigation lead and requested fix

    Read-only inspection of this installed build found that isFullReconciliationDue returns true when the initial build is incomplete or lastFullReconciliationAt is null; that predicate itself has no elapsed-time condition. This is a code-inspection lead, not proof of the complete runtime root cause.

    Could maintainers investigate:

    • Periodic/bounded authoritative reconciliation after initial indexing, so missed cross-device deletion events eventually self-heal.
    • Local invalidation for authoritative conversation_deleted responses, including conversations not currently loaded in the renderer, without treating generic network failures or permission errors as deletion.
    • A supported Refresh/Rebuild conversation index action that preserves cloud data, project chats, and local tasks.

    Is there a released or upcoming desktop build that fixes this path, or a supported way to request full reconciliation without manual database edits?

    Related iPhone-to-Mac ghost-entry report: #42768.

    This report intentionally omits conversation titles, IDs, account identifiers, screenshots of private chats, and raw logs.

  3. junzheliu01-code commented on Sep 13, 2026

    @junzheliu01-code

    Related to #44013. I reproduced a narrower migration/recovery case on macOS using a disposable clone.

    The imported paginated JSONL referenced a missing source rollout through history_base. The raw JSONL still contained 15 user messages and 42 assistant messages, but the migrated thread was treated as already paginated and its thread_history projection had 0 turns and 0 items.

    Changing history_mode to legacy allowed the task to open, but the transcript was blank. After normalizing the clone into a standalone paginated rollout (contiguous ordinals, invalid history_base removed) and resuming it once, the projection rebuilt successfully with 15 turns and 284 items.

    Implementation suggestions:

    1. Do not classify every paginated rollout as already_paginated. Validate lineage, ordinal continuity, and projection-cursor consistency.
    2. Add a safe per-thread rebuild-index/reindex operation that refuses active writers, resets only the target projection, rebuilds it from the canonical rollout, verifies non-empty results, and is idempotent.
    3. If a referenced source rollout is missing, distinguish an actually incomplete lineage from a self-contained migrated rollout that can be explicitly normalized.
    4. Preserve project_id during import so restored tasks remain in their projects.

    No raw transcript, SQLite database, private identifiers, or local paths are attached.

  4. akunilovskii commented on Sep 22, 2026

    @akunilovskii

    Confirmed on Windows with a different deletion path: chats deleted through Codex Agent Command Center remain visible in the desktop project's task list.

    Environment:

    • Installed Windows package: OpenAI.Codex_26.915.4065.0_x64 (executable: ChatGPT.exe). Version read from the installed package path.
    • Windows build 10.0.26200, x64.

    Reported sequence:

    1. Delete existing project chats through Codex Agent Command Center.
    2. Open the same project in the desktop app.
    3. The app still shows 11 tasks: 2 current chats and 9 previously deleted chats.
    4. Fully quit and reopen the desktop app. The stale entries remain.

    Read-only local database inspection confirmed the discrepancy:

    Storage Result for the 11 displayed project tasks
    ~/.codex/state_5.sqlite, threads The 2 current chats exist; all 9 stale IDs are absent.
    ~/.codex/sqlite/codex-dev.db, local_thread_catalog All 11 entries remain under host_id = 'local'; the 9 absent chats have missing_candidate = 0.

    Clearing the stale project assignments and ordering references in .codex-global-state.json did not resolve the UI problem. After a full quit/relaunch, those JSON structures still contained only the 2 current chats, while the desktop continued showing 11. The separate catalog retained all 11 entries.

    This points to a missed deletion/invalidation or reconciliation step in the desktop catalog. The exact Agent Command Center deletion implementation and event delivery have not been traced, so that remains a hypothesis rather than a confirmed code-level cause. The deletion itself was reported by the user; the subsequent database mismatch and persistence after relaunch were verified during diagnosis.

    Expected: deleting a local chat through Agent Command Center should also remove its desktop catalog/sidebar entry. Relaunch or reconciliation should clear a stale entry when its source thread is confirmed absent.

    Workaround confirmed by the user: the final cleanup script removed the 9 stale entries from the desktop catalog, and they disappeared from the desktop UI. The script checks that each targeted ID is absent from the source thread database, backs up the catalog, and preserves the 2 current chats. Chat history is not deleted. Cleaning the JSON sidebar references alone had not worked; the successful version also removed the stale local_thread_catalog rows. The diagnostic findings above were collected before that catalog repair. No chat contents, thread IDs, account IDs, or user-specific paths are included here.

  5. yusuke1827hmku-eng commented on Sep 29, 2026

    @yusuke1827hmku-eng

    Confirmed recurrence on macOS in ChatGPT Desktop / Codex 26.917.71314, build 10954, bundle com.openai.codex, on September 29, 2026.

    After a targeted catalog repair on September 19 and a verified successful full reconciliation, newly deleted conversations have accumulated as stale entries again. This is recurrence with different conversation IDs, rather than the repaired entries returning.

    Verified observations

    • The user reports that deleting chats on mobile/web leaves entries in desktop.
    • For the user's current example, opening the conversation URL in the authenticated web client redirects to the home page, while the local catalog retains that exact ID with source_kind=chatgpt and missing_candidate=0.
    • Separately, logs contain conversation_deleted for three other IDs that still have visible catalog rows.
    • The ChatGPT catalog's last_full_reconciled_at remains September 19, 2026 at 20:24:57 JST, the previous repair's verified reconciliation time. Initial construction is complete and normal updates have continued.
    • The previous repair backed up the SQLite database, removed three previously confirmed deleted rows, and requested one full reconciliation. It did not modify the app bundle. No database or app changes were made during this recurrence investigation.

    Narrow code-inspection lead

    Read-only inspection of the currently installed bundle found:

    1. isFullReconciliationDue checks only incomplete initial construction or a missing full-reconciliation timestamp. It has no elapsed-time condition.
    2. After initial construction, normal synchronization and notification-loss recovery request incremental scans. The scan completion path marks unseen entries missing only for a full scan.
    3. A WebSocket handler for conversation-deleted does exist and removes entries. The concern is recovery after missed events, not an assertion that deletion notifications are entirely absent. The precise notification-loss timing in this incident is unverified.

    Requested product fix

    Please add bounded authoritative reconciliation after startup, reconnection/missed notifications, and an elapsed interval, or provide deletion tombstones in incremental history. An authoritative conversation_deleted response should also invalidate the stale index entry, including when that conversation is not currently loaded. Preserve valid entries on network/authentication failures or partial pagination.

    Please verify with disposable chats deleted while desktop is closed, while disconnected, and while connected. Also cover pagination, archived/project chats, and failed/partial fetches. A supported Refresh/Rebuild conversation index action would help recovery, but repeated manual SQLite edits are not a permanent fix.

    Is a released build known to fix this path? The installed updater check returned busy, so no claim is made about update eligibility or the latest build's behavior.

    No conversation titles, conversation/account IDs, user paths, chat contents, screenshots, credentials, or raw logs are included. The reproduction sequences above are requested regression tests; they were not newly executed with disposable chats in this investigation.

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

    appIssues related to the Codex desktop appbugSomething isn't workingsessionIssues 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