Codex Desktop hides searchable local threads and shows stale/recent dates after path migration

Open 💬 4 comments Opened Jun 5, 2026 by haoliangli
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

What happened

After local project path migration / session migration, Codex Desktop shows inconsistent thread history for local projects:

  1. Some historical threads exist on disk and can be opened by exact thread id, but they do not appear in the project sidebar or search results.
  2. thread/list / Desktop project grouping returns fewer threads than state_5.sqlite and the raw rollout store for the same cwd.
  3. The Desktop UI sometimes displays many old conversations as recently updated (for example, "within 30 minutes"), even though the SQLite created_at / updated_at timestamps are much older or only a small subset changed.
  4. Pinning a thread by id makes some hidden threads visible, but search still may not find them by title.

This looks like an app-server / Desktop search-index / project-grouping cache issue rather than data loss.

Environment

  • Codex Desktop app build: 26.602.30954 (prod)
  • Bundled Codex CLI: codex-cli 0.137.0-alpha.4
  • OS: macOS 26.5.1 (25F80)
  • Local state DB: ~/.codex/state_5.sqlite
  • Session store: ~/.codex/sessions/**/rollout-*.jsonl
  • Archived session store: ~/.codex/archived_sessions/*.jsonl

Evidence

The counts below were collected with a local read-only diagnostic comparing raw rollout files, SQLite, and app-server thread/list for exact cwd values.

Project A:

  • raw rollout count: 30
  • SQLite thread count: 30
  • app-server thread count: 4
  • explicit project config: true
  • diagnosis: app-server filtering or metadata issue
  • Desktop search for project-specific keywords returns no threads, while direct thread reads by id work.

Project B:

  • raw rollout count: 60
  • SQLite thread count: 60
  • app-server thread count: 53
  • explicit project config: true after adding config
  • direct reads by id work, but global search by exact title sometimes returns no results.

Project C:

  • raw rollout count: 6
  • SQLite thread count: 6
  • app-server thread count: 6
  • direct thread reads work
  • one interrupted thread could be opened by id but was not searchable by its title.

Example symptom:

  • read_thread(<thread_id>) succeeds and returns title/turns.
  • list_threads(query=<exact title substring>) returns [] for the same thread.
  • Pinning that thread id succeeds and may make it visible in the sidebar.

Timestamp / date display issue

The Desktop UI showed many historical conversations as updated within the last ~30 minutes. A SQLite check did not fully match that display:

  • total threads in SQLite: 273
  • updated within 30 minutes at the time of check: 1
  • updated within 2 hours: 5
  • top repeated updated_at values included older migration timestamps such as 2026-04-19 and 2026-04-18, plus a small repeated batch at 2026-06-05 09:42:03.

This suggests the UI may sometimes display a sidebar/index refresh time, project grouping metadata time, or app-server metadata time instead of the thread's own updated_at.

Why this seems like a bug

The underlying records are still present:

  • raw rollout files exist
  • SQLite threads.cwd rows exist
  • direct reads by thread id work

But the Desktop sidebar/search and app-server project listing can hide or mis-date those same threads.

Expected behavior

For a local project cwd, if raw rollout files and SQLite agree, Codex Desktop / app-server should:

  1. show the same non-archived local threads in the project sidebar, or explain the active filter;
  2. find a thread by exact title substring in search;
  3. show the thread's actual updated_at / creation date, not an index refresh time;
  4. keep behavior stable after path migration and app restart.

Actual behavior

  • Project sidebar and search are incomplete.
  • Direct id-based reads work while title search fails.
  • Date display can show old threads as recently updated.
  • Restarting the app can partially change the visible set, suggesting cache/index instability.

Notes

I am not attaching raw session transcripts or app logs here because they may contain private local paths and conversation contents. I can provide sanitized diagnostics or submit feedback through the in-app /feedback flow if needed.

View original on GitHub ↗

4 Comments

github-actions[bot] contributor · 2 months ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #26634
  • #25463
  • #25574
  • #26157
  • #25500

Powered by Codex Action

haoliangli · 2 months ago

Additional sanitized finding and local mitigation:

I found a strong trigger for the wrong updated-time behavior. A local metadata/text migration had touched many Codex session JSONL files without changing the actual conversation end time. After that, Desktop/app-server showed many old conversations as recently updated at the same few seconds.

Evidence from the affected machine:

  • 162 session JSONL files had filesystem mtimes clustered at 2026-06-05 09:40-09:50 local time.
  • 158 of those had mtimes that differed from the authoritative threads.updated_at value in ~/.codex/state_5.sqlite.
  • state_5.sqlite still had the correct per-thread updated timestamps.
  • Before mitigation, app-server list_threads returned many old threads with updatedAt equal to the clustered filesystem mtime values.
  • Direct read_thread by id worked, but some title searches did not find the thread.

Local mitigation tested:

  • Backed up current JSONL atime/mtime metadata.
  • Restored affected JSONL file mtimes from SQLite threads.updated_at; did not modify file contents or the SQLite DB.
  • After restoring mtimes, app-server list_threads ordering improved immediately, the previously hidden thread appeared in the recent list, and exact title search found it again.

Hypothesis:
Desktop/app-server is using session JSONL filesystem mtime, or an index derived from mtime, as updatedAt / recency/search freshness in at least some paths. This makes history ordering fragile when local migration, backup, or text rewrite tools touch session files. The app should derive conversation recency from session content or state_5.sqlite thread metadata, not file mtime alone.

haoliangli · 2 months ago

Additional sanitized dot-directory project finding:

After restoring session file mtimes, normal workspace project history recovered much better. However, projects whose cwd is a dot-directory under the home directory still show search/list inconsistencies.

Observed examples:

  • cwd /Users/ray/.codex: raw rollout count 3, SQLite thread count 3, app-server project diagnose count 3, explicit project config true after adding [projects."/Users/ray/.codex"]. Direct read_thread by id succeeds for all 3. But global list_threads search for terms from those thread titles, such as MCP or codex name, returns no results.
  • cwd /Users/ray/.openclaw: raw rollout count 20, SQLite thread count 20, app-server project diagnose count 19 active threads (the missing one is archived), explicit project config true after adding [projects."/Users/ray/.openclaw"]. Direct read_thread by id succeeds, but global search for OpenClaw / openclaw 配置 returns no results.

This suggests a remaining Desktop/app-server indexing or global-search issue for hidden/dot-directory project cwd values, even when raw storage and app-server project-level diagnosis can see the threads.

aidawilliam41-ops · 1 month ago

Additional Windows evidence confirms a three-layer inconsistency between canonical thread storage, the app-server list/catalog, and the renderer sidebar.

Environment:

  • Codex Desktop/MSIX: OpenAI.Codex 26.715.4045.0
  • Bundled app-server: 0.145.0-alpha.18
  • Windows 11 x64

Observed:

  • The affected non-archived thread remained present in canonical state and its rollout JSONL was valid: 7,116 lines, 0 invalid lines.
  • Direct read by thread ID continued to work.
  • The derived local_thread_catalog had no row for that thread; its sync state showed initial_build_complete=0 and watermark=null.
  • list_threads initially omitted the thread even though canonical storage could read it.
  • A normal service turn later caused list_threads to return the thread again, but the already-running renderer sidebar still did not display it.
  • A title update initially returned No Codex thread found, then succeeded after the index/list state refreshed, confirming that the thread itself had never been missing.

No manual SQLite or global-state write was performed, and there was no data loss.

This suggests that canonical storage, the derived local catalog, the app-server list response, and renderer membership can diverge independently. A supported catalog rebuild/refresh path and explicit diagnostics for missing catalog rows would make this recoverable without state surgery.