Desktop app sidebar only shows loaded recent subset, not full workspace history

Resolved 💬 8 comments Opened Mar 15, 2026 by chenjingdev Closed Apr 3, 2026
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

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

26.311.21342

What subscription do you have?

GPT Pro

What platform is your computer?

Darwin 25.3.0 arm64 arm

What issue are you seeing?

Older workspace conversations still exist locally and are visible in Codex CLI, but disappear from the Codex Desktop App sidebar unless they are pinned or recently updated.

This looks like a sidebar/history loading issue rather than actual data loss.

Observed example: conversations under a workspace such as webmcp-dom remain present in local history and in CLI, but only a subset appears in the Desktop App.

What steps can reproduce the bug?

  1. Have a workspace with many older conversations and more than ~50 recent conversations overall.
  2. Confirm those workspace conversations still exist in Codex CLI / local history.
  3. Open the Codex Desktop App and check the sidebar.
  4. Observe that only a subset of that workspace's conversations appears.
  5. Pinning a hidden conversation can make it visible.
  6. Unpinning it and restarting the app can make it disappear again.

Additional local observation:

  • If a hidden conversation is moved upward in recency, it reappears in the app.
  • That suggests the sidebar is driven by a preloaded recent subset rather than full workspace history.

What is the expected behavior?

Expanding a workspace in the Desktop App should show the workspace's full conversation history, or fetch additional pages for that workspace.

Existing conversations should not disappear from the sidebar just because they are older than the startup recent window.

Additional information

Local investigation suggests the Desktop App starts with a recent conversation request like thread/list(limit=50, sortKey=updated_at) and receives a next_cursor, but the normal sidebar/workspace UI does not appear to page in older conversations when expanding a workspace.

Codex CLI can still see the same conversations, so this appears to be a Desktop App sidebar/history loading bug rather than actual history loss.

View original on GitHub ↗

8 Comments

github-actions[bot] contributor · 4 months ago

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

  • #14370
  • #13713
  • #14389

Powered by Codex Action

chenjingdev · 4 months ago

Additional debugging notes:

I dug into this locally a bit more and the behavior looks consistent with a sidebar data-loading issue rather than local-history loss.

What I observed:

  • The missing threads still exist locally and remain visible in Codex CLI.
  • On startup, the Desktop App appears to fetch recent conversations with something equivalent to thread/list(limit=50, sortKey=updated_at).
  • The thread/list response includes next_cursor, so the backend/app-server pagination path exists.
  • However, the normal workspace sidebar flow does not appear to page in older conversations when expanding a workspace.
  • In practice, the sidebar behaves like "group the already-loaded recent subset by workspace" rather than "load the workspace's actual thread history".

Why I think this is the root cause:

  • Pinning a hidden thread makes it show up.
  • Unpinning + restart can hide it again.
  • Moving a hidden thread upward in recency makes it reappear.
  • The same thread stays visible in CLI the whole time.

Possible fixes, in order of preference:

  1. Best: when expanding a workspace in the Desktop App, query/fetch that workspace's actual thread history directly instead of grouping only preloaded recents.
  2. Good fallback: when expanding a workspace, continue paging with next_cursor until enough matching threads for that workspace are loaded or pagination is exhausted.
  3. Partial mitigation only: increase the startup recent window, although that would only delay the problem for users with larger histories.

So my current guess is that the bug is in the Desktop App renderer/sidebar loading path, not in local persistence and not in thread storage itself.

Happy to add more repro details if useful.

chenjingdev · 4 months ago

I put together a small local mitigation for this while debugging it:

chenjingdev/codex-sidebar-refresher

What it does:

  • reads saved workspace roots from ~/.codex/.codex-global-state.json
  • finds direct threads whose cwd exactly matches those roots
  • excludes exec, subagent, and already pinned threads
  • updates only threads.updated_at in ~/.codex/state_5.sqlite
  • restarts Codex so those existing threads move back into the startup recent set and become visible in the Desktop sidebar again

What it does not do:

  • it does not recover deleted/missing conversation data
  • it does not modify sessions/*.jsonl
  • it does not fix the underlying Desktop App sidebar/history loading bug

So this is only a temporary local workaround for people blocked by the current behavior. It effectively re-promotes already-existing local threads so the app loads them again.

The script makes a backup first under ~/.codex/repair-backups/..., but it does rewrite updated_at, so recent ordering will change.

Example usage:
./scripts/refresh-visible-workspaces.sh --threads-per-root 3
or
./scripts/refresh-visible-workspaces.sh --total-threads 50

Current implementation is macOS-oriented because it force-restarts the local Codex app after updating the local state DB.

iqdoctor · 3 months ago

You can ask Codex to patch the Codex plugin as described in #15368. It worked surprisingly well for me. Just give Codex the link.

thephotocrv · 2 months ago

I am seeing the same issue on macOS with Codex Desktop 26.422.21637 (CFBundleVersion 2056).

The important part: local data is not missing. The threads exist in ~/.codex/state_5.sqlite, but Codex Desktop only loads a global window of recent threads and then projects appear incomplete or as if they had no chats.

Current local evidence:

  • ~/.codex/state_5.sqlite has the expected project threads:
  • Crv_PM: 14 active threads
  • WebPhotoCRV: 8 active threads
  • AyudaCodex: 5 active threads
  • ~/.codex/.codex-global-state.json is not empty:
  • active_roots: 3
  • thread_titles: 27
  • thread_order: 27
  • ~/.codex/session_index.jsonl: 27 entries
  • Codex telemetry in ~/Library/Application Support/Codex/sentry/scope_v3.json repeatedly reports:
  • thread_count_total: 50
  • thread_count_loaded_recent: 50

I also inspected /Applications/Codex.app/Contents/Resources/app.asar and found the recent thread loader starts with:

pageCount=1
refetchThreadList(...) -> limit: 50 * this.pageCount
loadNextThreadListPage(...) -> limit: 50

This matches the observed behavior: if a workspace/project has threads outside the initial global recent window, the Desktop UI does not show the complete project even though the local SQLite data is present.

I tried the usual safe steps:

  • reinstalling Codex.app
  • clearing app cache / local app support
  • checking global-state and session_index
  • reorganizing project folders

None of those fixed the issue because the underlying thread data was already present.

Expected behavior:

  • When expanding a project/workspace, Desktop should fetch/list threads for that specific cwd/workspace, not only rely on the initial global recent-thread window.
  • Alternatively, RECENT_CONVERSATIONS_PAGE_SIZE should be configurable or much larger.
  • By project should not show incomplete projects just because their threads fell outside the initial recent window.

This is a serious workflow blocker for projects with more than a handful of threads.

thephotocrv · 2 months ago

Additional local finding after deeper testing. This may help isolate the actual Desktop reindexing bug:
the issue is not only the 50 global recent-thread limit. There is also a reindexing/source-of-truth mismatch.

Root cause observed locally:

Codex Desktop does not reliably render project thread visibility from state_5.sqlite or session_index.jsonl alone. The UI state appears to be derived from the mtime of the rollout-*.jsonl files under:

~/.codex/sessions/
combined with the global recent-conversations preload limit of 50.

Concrete reproduction:

I had a project with 14 active threads in state_5.sqlite.
All 14 had the same exact cwd.
None were archived.
git_branch, git_sha, and worktree-related fields were not different.
Updating only state_5.sqlite updated_at / updated_at_ms did not make the hidden threads appear in Codex Desktop.
Updating session_index.jsonl and .codex-global-state.json also did not make them appear.
Codex Desktop reverted/recomputed the SQLite updated_at values on launch.
The values it restored matched the filesystem modification times of the corresponding rollout-*.jsonl files.
After updating both:
SQLite updated_at / updated_at_ms
the mtime of each corresponding rollout-*.jsonl
The project immediately showed all 14 threads in the UI.
So the effective UI source of truth seems to be:

rollout-*.jsonl mtime -> reindex -> SQLite/session index -> UI
or at least the rollout file mtime participates in reindexing strongly enough to override manual SQLite/index changes.

This explains why users see projects with missing threads even when local data exists and SQLite counts are correct.

Expected behavior:

Project thread lists should be resolved by project/workspace cwd, not only by a global recent window.
The UI should not report a project as empty or partially empty when valid local threads exist for that exact cwd.
Reindexing should use a stable thread metadata source, not filesystem mtime as a hidden effective source of truth.
If mtime is intentionally used, it should be documented and kept consistent with SQLite/session metadata.
Requested fix:

Increase the global recent conversations preload from 50 to at least 200.
Ideally make it configurable, e.g. in ~/.codex/config.toml:
recent_conversations_page_size = 200
or allow an unlimited / “load all local project threads” mode.

Even better:

When expanding a project, query local threads by cwd / project root directly.
Do not depend on whether those threads happen to be in the latest 50 global recent conversations.
Add proper pagination/search for local project threads.
Make “By project” actually load all local threads for that project.
Current workaround:

I created a local script that, with Codex Desktop closed:

backs up state_5.sqlite
backs up .codex-global-state.json
backs up session_index.jsonl
backs up the affected rollout-*.jsonl
updates SQLite updated_at
updates the corresponding rollout file mtime
rebuilds session_index.jsonl
limits visible projects to the active project plus a helper project
After doing this, the project becomes visible again in Codex Desktop.

This is not a real fix. It is only a workaround to force Codex Desktop to reindex hidden local threads.

Please fix this in Desktop. A hardcoded global recent-thread window of 50 is far too low for real Codex usage, because many users create many threads due to context limits, not because they want fragmented project history.
thephotocrv · 2 months ago

Additional external confirmation: after another update, the same bug remains but the compiled patch target moved again.

In extension version 26.5422.21459, the relevant logic moved to:

webview/assets/app-server-manager-signals-DaIWbgQQ.js

The conceptual patch points are still:

  • refetchThreadList(...)
  • loadNextThreadListPage(...)
  • global recent thread list limit around 50

A local workaround reportedly changed the initial refresh from:

listRecentThreads({ limit: 50 * this.pageCount, cursor: null })

to a full traversal helper, and raised load-more page size from 50 to 500.

This reinforces that the underlying bug is unchanged, but the compiled implementation keeps moving between builds. A local bundle patch is therefore not a maintainable solution.

Please expose an official setting or fix project thread loading so project views query all local threads by project/cwd instead of depending on the latest 50 global recent threads.

pgajer · 2 months ago

I can still reproduce what looks like the same Desktop sidebar/history issue on:

  • Codex Desktop: 26.422.71525 (CFBundleVersion 2210)
  • Platform: macOS / Darwin 25.3.0 arm64

Local evidence from one affected workspace:

  • The project is present in .codex-global-state.json:
  • project-order: yes
  • electron-saved-workspace-roots: yes
  • thread-workspace-root-hints: has matching entries
  • The same project has 5 active rows in ~/.codex/state_5.sqlite with:
  • archived = 0
  • has_user_event = 1
  • The newest affected thread is rank 75 by updated_at among active user-event threads; the other affected threads are ranks 212, 214, 215, and 227.
  • In Codex Desktop, opening that project from the sidebar still shows No chats.

This matches the suspected first-page behavior described here: the affected project’s newest thread is just outside the initial 50 recent-thread window, while newer projects show normally.

One additional observation: I tried a local workaround that added many older thread IDs to pinned-thread-ids; that made some project groups disappear from the sidebar, so large-scale pin hydration does not look like a safe workaround. A very small project-specific pin test is still pending.

No raw rollout/session files were attached because they may contain private source paths, prompts, and project content.