Codex Desktop hides active local threads from sidebar/search while state_5.sqlite still marks them unarchived

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

Summary

Codex Desktop appears to hide some active local threads from the left sidebar and sidebar search even though they still exist locally and are not archived.

This does not look like data loss. The affected threads remain present in the local state database and their rollout files still exist, but the Desktop UI no longer provides a reliable way to discover or continue them from the sidebar.

Environment

  • Codex Desktop: 26.602.71036
  • Codex CLI: 0.137.0-alpha.4
  • Platform: macOS
  • Local threads / desktop app usage
  • Affected threads include project-backed threads, projectless threads, and worktree-backed threads

What I observed

For affected thread IDs:

  • ~/.codex/state_5.sqlite contains the thread rows
  • threads.archived = 0
  • threads.archived_at IS NULL
  • threads.source = vscode
  • threads.rollout_path points to existing session JSONL files
  • Some affected thread names are still present in ~/.codex/session_index.jsonl
  • Reading/resuming by direct thread ID still works
  • The threads are missing from the Codex Desktop left sidebar
  • Sidebar search does not find some of the affected threads by title or ID

The affected threads seem to fall into multiple categories:

  1. Threads whose cwd is under a project/workspace root but are older than the recent sidebar window.
  2. Threads whose cwd is a worktree path that is no longer present in electron-saved-workspace-roots / project-order.
  3. Threads whose cwd uses a path that differs from a saved workspace root by path spelling/casing, for example a canonical project root vs another similarly named root.
  4. Projectless or Codex-managed threads that exist locally but are not reliably discoverable through the sidebar.

Relevant local state fields

The following fields appear related to sidebar visibility / grouping:

  • electron-saved-workspace-roots
  • active-workspace-roots
  • project-order
  • projectless-thread-ids
  • pinned-thread-ids
  • thread-workspace-root-hints
  • thread-projectless-output-directories

The app bundle also appears to reference newer sidebar/project metadata fields such as:

  • thread-project-assignments
  • sidebar-project-thread-orders
  • sidebar-thread-metadata
  • sidebar-chat-thread-order
  • local-projects
  • project-writable-roots

However, it is not clear which of these are authoritative, derived, stale, or safe for users/tools to inspect.

Expected behavior

Active, unarchived local threads should remain discoverable and resumable from the Desktop UI, either through:

  • the relevant project sidebar,
  • a full chronological/all threads view,
  • sidebar search,
  • or an official local thread management UI.

Search should include all persisted local threads, not only the currently loaded recent sidebar subset.

Project/worktree grouping should not make active threads effectively disappear.

Actual behavior

Some active, unarchived local threads are hidden from the sidebar and sidebar search. The only reliable way to access them is by knowing the thread ID in advance and using a direct thread read/resume path or deep link.

This makes long-term local thread management difficult because the Desktop sidebar cannot be treated as the source of truth for active conversations.

Questions

Could the Codex team clarify the intended model for local thread management?

  1. Is the Desktop sidebar expected to show all active local threads, or only a recent subset?
  2. Is there an official command/API to rebuild or refresh the local sidebar/search index?
  3. Is state_5.sqlite.threads the supported source of truth for local active threads?
  4. Is session_index.jsonl authoritative, derived, or cache-only?
  5. Is there an official way to list all active local threads across projects, projectless chats, and worktrees?
  6. What is the recommended recovery path when a thread is active and unarchived locally but hidden from the sidebar?
  7. How should worktree-backed threads be associated back to their owning project?
  8. Are tools expected to use app-server thread/list / thread/read for full local thread management, and if so, is that API stable enough for user-facing thread dashboards?

Related issues

This seems related to several existing reports:

  • #10522
  • #14751
  • #20254
  • #20833
  • #21128
  • #22592
  • #23979
  • #25084
  • #25119

The common theme is that local thread data remains present and unarchived, but Desktop sidebar/search visibility diverges from the local state database.

Suggested improvement

A robust fix could include:

  • Full pagination by project/workspace root, not only a global recent-thread window.
  • Sidebar search over all persisted local threads.
  • A supported "rebuild local thread index" command.
  • A documented source of truth for local threads and sidebar metadata.
  • A first-party "All Local Threads" view with filters for active/archived/project/worktree/projectless.
  • Stable deep links for every local thread.

View original on GitHub ↗

19 Comments

github-actions[bot] contributor · 1 month ago

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

  • #26647
  • #26157
  • #25761
  • #26886
  • #26411

Powered by Codex Action

wendybzhang · 1 month ago

I reviewed the potential duplicates suggested by the bot.

The closest related issues seem to be #25761, #26157, and #26647:

  • #25761 covers the apparent global ~50 recent-thread sidebar limit.
  • #26157 covers project/sidebar mapping loss after updates while local sessions still exist.
  • #26647 covers path migration/search/index inconsistencies where direct thread reads work but sidebar/search do not.

This issue is probably in the same family, but I would like to keep the additional question visible unless maintainers prefer a specific canonical issue:

What is the supported way for users/tools to manage and recover all active local Codex threads when the Desktop sidebar/search is not a complete source of truth?

In my case the affected threads span:

  • project-backed threads,
  • projectless threads,
  • worktree-backed threads,
  • cwd/path-root mismatch cases,
  • active archived=0 rows in state_5.sqlite,
  • existing rollout files,
  • and successful direct reads by thread ID.

I am happy to close this as a duplicate if the team identifies a canonical tracking issue, but it would be very helpful to know whether users should rely on state_5.sqlite, session_index.jsonl, app-server thread/list, codex://threads/<id>, or some other supported mechanism for full local thread discovery and recovery.

BoldNewMedia · 1 month ago

Additional fresh reproduction on macOS, with private project names/paths redacted.

Environment:

  • Codex Desktop: 26.602.71036 (CFBundleVersion 3685)
  • Bundle identifier: com.openai.codex
  • Codex CLI: codex-cli 0.130.0
  • Platform: macOS

Observed local state:

  • ~/.codex/state_5.sqlite contains 177 unarchived local threads.
  • 141 of those unarchived threads have cwd matching saved project roots.
  • 33 are date-stamped/projectless local chats.
  • 3 are other unarchived local threads.
  • electron-saved-workspace-roots contains 16 saved roots.

Current sidebar behaviour:

  • After repairing project metadata (thread-project-assignments, thread-workspace-root-hints, projectless-thread-ids, session_index.jsonl), every non-empty project can be made to show at least some chats.
  • However, many chats still remain inaccessible from the sidebar because Desktop only hydrates the first recent page.
  • In the first 50 rows currently loaded by the sidebar, there are 47 saved-project threads and only 3 projectless chats, even though the local DB has 33 projectless chats in total.
  • Reading hidden thread IDs directly still works, so this does not appear to be local data loss.

Renderer/app bundle evidence on this install:

async loadMoreRecentConversations(){
  if(!this.hasMoreRecentConversations())return;
  await this.loadThreadHydrationState();
  let e=await this.listRecentThreads({limit:50,cursor:this.nextRecentConversationCursor});
  ...
}

Update after local unsupported patch test:

  • I backed up the app bundle resources, changed the two sidebar loader calls from limit:50 to limit:500, repacked app.asar, reinstalled the matching app.asar.unpacked, and locally re-signed the app.
  • Verified patched calls:
  • listRecentThreads({limit:500,cursor:this.nextRecentConversationCursor})
  • listRecentThreads({limit:500*this.recentConversationPageCount,cursor:null})
  • After fully quitting and relaunching Codex Desktop, the previously missing project and projectless chats reappeared in the sidebar.

This strongly confirms the issue is the hardcoded recent-thread hydration window, not local data loss. The app-bundle patch is only a local workaround and will likely be overwritten by future Codex updates.

Impact:

  • Users with more than 50 local active chats can see projects partially restored but still cannot access all project chats or all projectless chats through the normal sidebar.
  • The UI still makes valid local history look missing unless the user knows how to inspect SQLite or knows exact thread IDs.

Requested fixes:

  • Sidebar should auto-page beyond the first 50, or use project/workspace-specific pagination when expanding a project.
  • Projectless chats should have their own complete pagination, not just whatever happens to fall into the global recent page.
  • Sidebar search should query all persisted local threads, not only the hydrated recent subset.
  • Please provide a supported rebuild/reindex/recover command for local Desktop thread visibility.
jvanakker · 1 month ago

Same for me, but one difference: Using search within Codex Desktop still finds results in at least some of the disappeared chats. They are indeed still there, they're just not listed anymore under the projects in the UI. Clicking a search result results in an empty chat window, so we still have no way to access these old chats. Hoping for a fix soon..

nostitos · 1 month ago
Same for me, but one difference: Using search within Codex Desktop still finds results in at least some of the disappeared chats. They are indeed still there, they're just not listed anymore under the projects in the UI. Clicking a search result results in an empty chat window, so we still have no way to access these old chats. Hoping for a fix soon..

in case you're looking for a quick fix, That what my codex does after every update:

Patch /Applications/Codex.app/Contents/Resources/app.asar: replace the single byte string let t=await this.listRecentThreads({limit:50*this.recentConversationPageCount,cursor:null}); with same-length let t={data:await this.listAllThreads({modelProviders:null,archived:!1}),nextCursor:null}; , after backing up the original ASAR.

Then fully quit and reopen Codex.

defcc · 1 month ago
> Same for me, but one difference: Using search within Codex Desktop still finds results in at least some of the disappeared chats. They are indeed still there, they're just not listed anymore under the projects in the UI. Clicking a search result results in an empty chat window, so we still have no way to access these old chats. Hoping for a fix soon.. in case you're looking for a quick fix, That what my codex does after every update: Patch /Applications/Codex.app/Contents/Resources/app.asar: replace the single byte string let t=await this.listRecentThreads({limit:50*this.recentConversationPageCount,cursor:null}); with same-length let t={data:await this.listAllThreads({modelProviders:null,archived:!1}),nextCursor:null}; , after backing up the original ASAR. Then fully quit and reopen Codex.

Thanks. You're a life saver.

wangyaok1 · 1 month ago

Adding a macOS datapoint after updating to the latest Desktop build.

Environment:

  • macOS 15.5 (24F74)
  • Apple Silicon / arm64
  • Codex Desktop: 26.608.12217
  • CFBundleVersion: 3722
  • Local storage: default ~/.codex

Recovery status on my affected project:

  • The update appears to have restored some previously missing threads.
  • It did not restore everything.
  • Older project threads are still missing from the Desktop sidebar/project history.
  • The local data still appears to exist. For the affected project, state_5.sqlite still has 251 active/non-archived rows with the expected project cwd.
  • Earlier checks also confirmed matching rollout JSONL/session files under ~/.codex/sessions.

So my current result is: 26.608.12217 looks like a partial recovery, not a full recovery. It would still be very helpful to have an official full local reindex/recovery command that rebuilds sidebar/project history from durable local state.

zjy365 · 1 month ago

I built a small open-source helper for this: https://github.com/zjy365/codex-recall

It runs on localhost, searches local Codex sessions under ~/.codex, and has an experimental “restore to sidebar” action for one selected thread, with a backup first.

If anyone here tries it, I’d be interested to know: is the bigger need finding hidden sessions, or restoring one back into Desktop?

ashe0047 · 1 month ago
> Same for me, but one difference: Using search within Codex Desktop still finds results in at least some of the disappeared chats. They are indeed still there, they're just not listed anymore under the projects in the UI. Clicking a search result results in an empty chat window, so we still have no way to access these old chats. Hoping for a fix soon.. in case you're looking for a quick fix, That what my codex does after every update: Patch /Applications/Codex.app/Contents/Resources/app.asar: replace the single byte string let t=await this.listRecentThreads({limit:50*this.recentConversationPageCount,cursor:null}); with same-length let t={data:await this.listAllThreads({modelProviders:null,archived:!1}),nextCursor:null}; , after backing up the original ASAR. Then fully quit and reopen Codex.

Hi, seems like this snippet is no longer in the latest version of Codex app.asar. Could you confirm?

Tuizi · 1 month ago

I can reproduce this on macOS, including with recently active threads.

Environment

  • Codex Desktop: 26.609.30741 (build 3808)
  • Bundled Codex CLI: 0.140.0-alpha.2
  • macOS: 26.4.1
  • Architecture: arm64

Observed behavior

A recently active, project-backed thread disappeared from both the Desktop
sidebar and sidebar search.

However:

  • Direct access to the thread still worked.
  • The thread was unarchived.
  • Its workspace-root association was correct.
  • Its underlying work continued and completed normally.
  • Pinning or archive/unarchive could make it reappear temporarily.

This indicates a sidebar/indexing failure rather than session deletion or an
invalid workspace association.

Additional evidence

I compared persisted thread metadata with the Desktop listing:

  • One state snapshot contained 19 pinned thread IDs.
  • A later snapshot contained only 11.
  • Eight previously pinned IDs disappeared without intentional unpinning during

the audit.

  • Four threads that remained pinned were omitted from the broad recent listing.
  • Hidden threads remained readable by ID with their messages and state intact.
  • Both project-backed and worktree-backed threads were affected.
  • Some hidden threads were still active or required user follow-up.

A collapsed project group could explain some omissions, but not all affected
threads.

Suspected failure modes

  1. The sidebar groups only a globally paginated recent subset.
  2. Search examines the loaded subset rather than every persisted thread.
  3. Pinned-thread state can be rebuilt or synchronized inconsistently.
  4. Project/worktree grouping can hide valid threads.
  5. Pin or archive operations trigger only a temporary refresh.

Impact

A running agent can disappear from the supervision UI while continuing to
work. The user cannot reliably inspect, steer, stop, or collect its result
without already knowing its thread ID.

Requested improvements

  • An “All Local Threads” view with complete pagination.
  • Search across every persisted thread.
  • A supported sidebar/index rebuild operation.
  • Durable pinned-thread state.
  • A guarantee that active threads remain visible.

I submitted in-app feedback containing the private session details.

Feedback/session ID: 019eb8a7-687e-73f3-9225-7886685edd86

Noa-DistriCar · 1 month ago

I can reproduce a very similar issue in the VS Code Codex extension on Windows.

Environment:

  • VS Code Stable: 1.124.2
  • Codex/OpenAI extension: openai.chatgpt 26.609.30741
  • Platform: Windows
  • Context: local workspace
  • Model: gpt-5.5

Observed behavior:

  • A Codex task was visible in the VS Code Codex Tasks/history UI before restarting VS Code.
  • After closing and reopening VS Code with the exact same workspace, that specific recent task disappeared from the visible Tasks/history list.
  • Older tasks were still visible.
  • This looked like selective UI history/task restore loss rather than general data loss.

Local evidence:

  • The affected thread/session was still physically present after restart.
  • The thread was still present in the local session index.
  • The thread was still present in state_5.sqlite under threads.
  • The thread state was still active.
  • The same workspace and same workspaceStorage identifier were used before and after restart.
  • The affected task was not present in the whitelisted VS Code UI-state export I inspected.

Classification from my local metadata-only investigation:
EXACT_SESSION_CORRELATED_UI_MISSING

This seems to match the pattern described in this issue: local Codex thread/session state remains present, but the VS Code/Codex UI no longer reliably hydrates or exposes the task in Tasks/history after restart.

aleksandr-kotlyar · 1 month ago
> > Same for me, but one difference: Using search within Codex Desktop still finds results in at least some of the disappeared chats. They are indeed still there, they're just not listed anymore under the projects in the UI. Clicking a search result results in an empty chat window, so we still have no way to access these old chats. Hoping for a fix soon.. > > > in case you're looking for a quick fix, That what my codex does after every update: > Patch /Applications/Codex.app/Contents/Resources/app.asar: replace the single byte string let t=await this.listRecentThreads({limit:50*this.recentConversationPageCount,cursor:null}); with same-length let t={data:await this.listAllThreads({modelProviders:null,archived:!1}),nextCursor:null}; , after backing up the original ASAR. > Then fully quit and reopen Codex. Hi, seems like this snippet is no longer in the latest version of Codex app.asar. Could you confirm?

For curr version:

I found that the current desktop bundle already has a feature-gated higher recent-thread discovery limit:

getRecentConversationDiscoveryLimit:()=>e!=null&&c&&e.get($t,`3314958849`)?500:50

As a local workaround, I patched the first && to || in /Applications/Codex.app/Contents/Resources/app.asar:

getRecentConversationDiscoveryLimit:()=>e!=null||c&&e.get($t,`3314958849`)?500:50

This forces getRecentConversationDiscoveryLimit() to return 500 instead of 50 in normal runtime, since e != null is true. After restarting the app, more recent unarchived threads became discoverable again.

This is only a local byte patch workaround and will be overwritten by app updates.

---

Update: my first workaround was not sticky enough.

The bundle already has a hidden/feature-gated recent-thread discovery limit:

getRecentConversationDiscoveryLimit:()=>e!=null&&c&&e.get($t,`3314958849`)?500:50

I first patched the first && to || to force the limit to 500:

getRecentConversationDiscoveryLimit:()=>e!=null||c&&e.get($t,`3314958849`)?500:50

That helps initially, but after the app runs for a while, threads can disappear again. The reason seems to be that routine refresh can still avoid the expanded-history path and the expanded path also slices the active recent conversation ids back to 50:

i=(t===`expanded`||n)&&r>50
...
c=e.slice(0,50)

The more stable local workaround was to patch those too:

i=(t===`expanded`||n)||r>50

and:

c=e.slice(0,r )

So the full current workaround is:

-getRecentConversationDiscoveryLimit:()=>e!=null&&c&&e.get($t,`3314958849`)?500:50
+getRecentConversationDiscoveryLimit:()=>e!=null||c&&e.get($t,`3314958849`)?500:50

-i=(t===`expanded`||n)&&r>50
+i=(t===`expanded`||n)||r>50

-c=e.slice(0,50)
+c=e.slice(0,r )

This keeps the recent-thread discovery limit at 500 and prevents routine refresh from collapsing the visible/recent thread ids back to 50.

This is still only a local byte-patch workaround for /Applications/Codex.app/Contents/Resources/app.asar; it gets overwritten by app updates. I backed up the original ASAR before patching and restarted the app afterwards.

ArtaFakhari · 5 days ago

Fresh Windows / VS Code reproduction with a narrower app-server discrepancy.

Environment:

  • Codex IDE extension: 26.707.71524
  • VS Code: 1.128.1 (5264f2156cbcd7aea5fd004d29eaa10209155d66, x64)
  • Codex CLI: 0.144.3
  • App-server user agent reported codex_vscode/0.144.2
  • Windows 10.0.26200, x64

Observed:

  • A recently active, project-backed user thread disappeared from the Codex VS Code sidebar.
  • The rollout JSONL remained intact (about 33 MB).
  • state_5.sqlite still contained the row with archived = 0, the correct project cwd, title, preview, and thread_source = user.
  • session_index.jsonl contained the thread name.
  • Exact thread/read succeeded and returned the expected thread with status.type = notLoaded.

App-server reproduction using the same local Codex home:

  1. thread/list with archived:false, limit:100, sortKey:updated_at, and useStateDbOnly:false returned 31 threads and omitted the affected ID.
  2. The same request with useStateDbOnly:true returned 32 threads and included the affected ID.
  3. thread/search then found the affected thread by its saved title.

Recovery attempt also exposed an archive/index inconsistency:

  • codex archive <id> reported success.
  • Immediate codex unarchive <id> returned Error: failed to unarchive session.
  • Despite that error, the final SQLite state was unarchived, the rollout file was restored under sessions/, no archived copy remained, and the session-index row was present again.

This looks like divergence between the normal filesystem/merged listing path and the state-database-only listing path, rather than data loss or a project-root mismatch. It would be helpful if the standard IDE list path converged with state DB results for valid unarchived threads, and if archive/unarchive were atomic or returned the actual final state. A supported sidebar reindex/rebuild command would also make recovery much safer.

Private repository names, paths, prompts, and the local thread ID are intentionally omitted.

ArtaFakhari · 5 days ago

Follow-up after a broader read-only inventory and rollback of all local workaround experiments. All identifiers, names, prompts, repository details, paths, and account information are omitted.

Data-loss check

  • Audited 40 user-owned root threads in the durable state database.
  • Every audited row still has a matching rollout JSONL file; zero transcript files were missing.
  • Session-index entries were also present for the affected threads.
  • This confirms the symptom is discovery/hydration failure, not deletion.

Normal list vs state-database list

Using the bundled VS Code app-server against the same Codex home:

  • thread/list with archived:false, limit:100, sortKey:updated_at, and useStateDbOnly:false returned 31 active threads.
  • The same request with useStateDbOnly:true returned 33 active threads.
  • The two additional state-DB results were the original affected thread and a newly created full-history fork of it.
  • Archived-thread counts agreed between both paths.

The full-history fork received a fresh ID and fresh rollout path, but the normal listing path omitted it exactly like the original. This indicates that the failure follows the copied transcript/history shape rather than the original thread ID, title, project assignment, or rollout filename.

Exact-read and empty-view evidence

thread/read with includeTurns:true succeeded for both the original and the fork:

  • Original: 7 logical turns, 371 hydrated items.
  • Full-history fork: the same 7 turns and 371 hydrated items.
  • Item types included user messages, agent messages, subagent activity, web-search records, context compactions, plans, and file-change records.

Despite those successful exact reads, the UI displayed the recovery fork as if its prior conversation were empty. So there are at least two related failure surfaces:

  1. Normal thread/list can omit valid active threads that the state-database path returns.
  2. A thread that is opened or otherwise surfaced can still render as empty even though exact read returns hundreds of hydrated items.

A separate active thread with 53 turns and 976 hydrated items was returned by both normal and state-database list paths, yet the user also could not locate it in the VS Code/Desktop history UI. This suggests an additional sidebar cache/grouping/pagination layer can hide threads even when app-server listing succeeds.

Extension implementation clue

The installed VS Code extension bundle initializes its local manager with supportsStateDbOnlyThreadList:false, while the bundled app-server successfully serves useStateDbOnly:true. This may explain why the IDE remains on the divergent merged/filesystem listing path even when the state database has a complete valid record.

Recovery safety

Archive/unarchive and UI-state experiments were fully rolled back. The original extension asset and global-state file were restored byte-for-byte from backups. The findings above were then reproduced using read-only database queries and app-server read/list/search requests.

Requested fixes:

  • Make normal and state-database listing converge for valid unarchived threads.
  • Ensure the IDE can use the state-database listing capability when supported by its bundled app-server.
  • Fix hydration so exact-readable turns cannot render as an empty conversation.
  • Make sidebar project/projectless grouping and pagination complete over the app-server result set.
  • Provide a supported read-only inventory/reindex command before users resort to risky manual recovery.
ArtaFakhari · 5 days ago

Additional crash/recovery finding (sanitized; no project, repository, path, session, account, or custom-skill names included):

Crash symptom

The VS Code Codex integration reported Codex process is not available during startup. The process log contained three errors saying local SKILL.md files were missing YAML frontmatter delimited by ---, even though each file visibly contained valid frontmatter.

Root cause

Byte-level inspection showed that each affected UTF-8 file began with a byte-order mark (EF BB BF) immediately before the opening ---. The skill loader did not tolerate the UTF-8 BOM and therefore treated the frontmatter as absent.

Recovery proof

  • Removed only the leading UTF-8 BOM bytes; skill contents and frontmatter were otherwise unchanged.
  • The official skill validator passed all three files when run explicitly in UTF-8 mode.
  • A fresh bundled Codex app-server process initialized successfully afterward.
  • The fresh process emitted zero skill-loading errors.

Requested hardening

  • Accept an optional UTF-8 BOM before the opening YAML frontmatter delimiter, or surface a precise UTF-8 BOM before frontmatter diagnostic rather than missing YAML frontmatter.
  • A malformed or unsupported local skill should be isolated and skipped without making the entire Codex process unavailable.
  • Ensure bundled Windows validation/loading paths consistently decode skill files as UTF-8 rather than inheriting a legacy system code page.

This startup crash appears distinct from the thread-list/hydration defect above, but it occurred during the same degraded client episode and made the affected Codex surface completely unavailable until the local files were repaired.

ArtaFakhari · 5 days ago

Further sanitized cross-client inventory after the user observed mutually inconsistent sidebars (no titles, IDs, prompts, paths, repository details, or account information included):

Cross-client split is reproducible

A read-only inventory found 34 active user-root records in the durable state database. All 34 still have matching, non-empty rollout files.

Against the same Codex home and bundled app-server:

  • Normal thread/list: 31 active user-facing threads.
  • useStateDbOnly:true: 33 active user-facing threads.
  • Two valid threads are returned only by the state-database path, including an original affected thread and its recovery copy.
  • One additional active root thread is omitted by both list modes, even though thread/read by exact ID succeeds for it (1 turn / 22 hydrated items).

The two installed clients then diverge again above the app-server layer: one thread returned by both backend list modes appears only in the IDE sidebar, while a state-only recovery thread appears only in Desktop. This demonstrates that client-side filtering/grouping/cache behavior is independently suppressing different members of the backend result set.

Transcript integrity sweep

All 34 active user-root rollout files were parsed read-only:

  • 34/34 files present and non-empty.
  • 33/34 parse completely as JSONL.
  • 0 empty transcripts.
  • 1 malformed record across the entire set.

The malformed record belongs to the thread that appears only in the IDE:

  • It is a single approximately 5.2 MB compacted record amid thousands of otherwise intact records.
  • The record contains 48 raw NUL bytes in three 16-byte runs inside embedded image-data strings.
  • The NUL bytes make the JSON record invalid.
  • Normal and state-database list calls still return the thread, but thread/read(includeTurns:true) does not return a result or a clean error within a bounded 75-second check.
  • Desktop logs contain activity for the thread, yet Desktop does not show it in history.

This adds a third distinct failure class to the earlier report:

  1. Normal listing omits state-database threads.
  2. Client sidebar filters suppress different threads even when backend listing returns them.
  3. A malformed large compaction record can leave a thread indexed/listable on one surface while exact hydration hangs and another client suppresses it.

Requested additional hardening:

  • Validate each appended JSONL record atomically and reject or quarantine raw control-byte corruption.
  • Put a size/time bound around compaction-record hydration and return a precise recoverable error instead of hanging.
  • Continue hydrating intact records when one compaction payload is malformed, with an explicit degraded-history warning.
  • Provide a supported read-only integrity checker and a backup-first repair command for corrupted rollout records.
  • Make both clients expose the same canonical active-thread inventory and distinguish hidden/filtered from missing/corrupt.
ArtaFakhari · 5 days ago

Sanitized local recovery result (no titles, IDs, prompts, paths, repositories, or account information included):

A backup-first repair was tested against an isolated cloned Codex home and then applied locally.

Corrupted compaction recovery

  • The affected rollout contained exactly three 16-byte NUL runs in one embedded-image compaction record.
  • A same-length 48-byte repair was validated against the clone before applying it live.
  • All 7,594 JSONL records now parse.
  • thread/read(includeTurns:true) changed from hanging beyond 75 seconds to completing immediately with 55 turns and 999 hydrated items.
  • The original rollout, state database, session index, and affected transcripts were preserved in a timestamped backup before mutation.

Empty-preview filtering recovery

A separate intact root thread had an attachment-based initial request but empty first_user_message and preview database fields. It was omitted by both list modes despite exact read succeeding. In the cloned database, restoring those two preview fields from the existing thread title caused useStateDbOnly:true to return it. The same metadata-only repair was then applied live.

Final backend verification

  • Normal list remains at 31 threads.
  • State-database list now returns all 34 active user-root threads.
  • Exact reads succeed for all four focus threads: 55/999, 7/371, 10/436, and 1/22 turns/items.
  • A temporary recovery fork created during testing was archived after proving it inherited the empty-preview omission.

Client workaround

The installed IDE bundle initializes its local manager with supportsStateDbOnlyThreadList:false. A one-byte, backup-preserved local patch changes that flag to true; the asset passes JavaScript syntax validation. After client reload, the IDE should consume the same complete 34-thread state-database inventory as Desktop.

This is only a local workaround and will be overwritten by an extension update. The product fix should enable the complete canonical listing path by default, backfill missing preview fields for attachment-originated conversations, and recover malformed compaction records without requiring byte-level user intervention.

ArtaFakhari · 5 days ago

Correction and final findings from a deeper client-level investigation (all identifiers and workspace details omitted):

The earlier metadata-only workaround was insufficient and should not be considered a UI fix.

I found several independent failure modes:

  1. The VS Code extension's normal recent-history/sidebar requests did not use the state-database-only list path, even though that path returned the complete active set. This caused valid local threads to be omitted from the rendered list.
  2. The Desktop app used a separate persistent local thread catalog. That catalog's initial build was incomplete while remote-history scans were failing (one remote lacked the Codex executable in PATH and another timed out).
  3. Desktop also retained a stale "projectless thread" assignment and workspace hint in global state. That assignment overrode the corrected catalog working directory and removed one valid thread from its project list.
  4. One local rollout contained a few embedded NUL-byte runs inside a compacted record. Its text history could be restored after a length-preserving repair, although one embedded image payload may remain damaged.
  5. Another valid thread had empty preview/first-message metadata, causing it to be filtered from the normal list despite an intact rollout.

Recovery actions were performed only after consistent backups:

  • repaired the malformed rollout and verified that every JSONL record parses;
  • repaired missing list metadata;
  • rebuilt the Desktop local catalog from verified active user-owned local threads;
  • removed the stale projectless assignment/hints;
  • forced the VS Code recent-history calls to use the complete state-backed list;
  • used Desktop's supported Pin action as an immediate visibility workaround because the running main process retained the old assignment in memory.

Direct UI verification now completed:

  • VS Code renders the complete active count and the previously omitted entries; multiple recovered threads were opened and showed populated conversation views.
  • Desktop visibly renders the recovered entries. The previously omitted thread is now persistently visible in the Pinned section and opens with a populated conversation.
  • A renderer reload alone does not refresh Desktop's main-process assignment cache, so regrouping that pinned thread under its project still requires a full Desktop process restart to verify.

The local VS Code bundle patch is only a diagnostic workaround and may be overwritten by an extension update. The product-level fixes should make the state-backed list behavior consistent across clients, make catalog rebuilds resilient to remote-host failures, avoid stale projectless assignments overriding valid catalog data, and surface rollout corruption instead of silently omitting history.

dong910607-tech · 3 days ago

Reproduced on macOS with ChatGPT/Codex desktop app 26.715.21425 (build 5488), local projects only. After update, project cards remain but task lists are empty; unfiltered default listing returns only 2 tasks. Data is intact: 128 local session transcripts remain; direct read/resume succeeds; targeted project-keyword search returns older tasks as notLoaded; navigation/resume does not repopulate the project/sidebar index. Project directories and permissions are intact. I did not clear cache, log out, uninstall, delete data, or edit session/index files. This comment intentionally omits account identifiers, project names, local paths, task contents, and logs. Expected: active local tasks remain discoverable in their project sidebar, or a supported non-destructive rebuild-index action is available.