Desktop sidebar shows "No chats" for all projects — thread/list with useStateDbOnly:true returns 0 threads when limit >= 50
What version of the Codex App are you using (From “About Codex” dialog)?
26.609.3341.0 (also observed on 26.608.1337.0); bundled runtime codex-cli 0.140.0-alpha.2
What subscription do you have?
ChatGPT Plus
What platform is your computer?
Microsoft Windows NT 10.0.26200.0 x64 (Windows 11 Home)
What issue are you seeing?
Since ~2026-06-10 the Codex Desktop sidebar shows "No chats" under every project, even though the local state DB (state_5.sqlite) contains 167 threads with correct cwd values and existing rollout files. Only pinned chats and threads that were active in the current session appear under projects. Search (thread/search) still finds every thread, and the mobile app (server-side listing) is unaffected — so no data is lost; the desktop listing path is broken.
Root cause (verified by speaking the app-server JSON-RPC protocol directly against the bundled runtime): the desktop UI now requests thread/list { limit: 500, sortKey: "updated_at", archived: false, useStateDbOnly: true } (expanded thread history path), and that request returns an empty result. The renderer then replaces its thread summaries with the empty list, so every project section renders "No chats". Pinned chats survive only because they are hydrated individually via thread/read.
The timing matches a remote feature-gate rollout (~2026-06-10/11) switching the sidebar from the legacy listing path (which still works, see below) to the state-db-only path.
What steps can reproduce the bug?
Feedback ID: no-active-thread-019eb7b0-ce2b-7692-9edb-bf0ea8a0e3fe
Minimal repro against codex app-server (codex-cli 0.140.0-alpha.2, Windows 11, CODEX_HOME with 167 threads / 165 unarchived):
- Start
codex app-server, sendinitialize→ ok. thread/list {"limit": 49, "cursor": null, "sortKey": "updated_at", "archived": false, "useStateDbOnly": true}→ returns 49 threads ✔- Same request with
"limit": 50→ returnsdata: [],nextCursor: null✘ - Same request with
"limit": 500(with or withoutsourceKinds) →data: []✘ - Same request with
"useStateDbOnly": false, "limit": 50→ returns 50 threads ✔ (correct cwd grouping)
Additional pagination bug in the same path: when the last row of a page has updated_at milliseconds ending in zero, nextCursor is emitted with trimmed fractional digits (e.g. 2026-06-02T08:04:03.74Z instead of .740Z). Passing that cursor back yields an empty page — the runtime cannot parse its own cursor. Walking pages of 10 sorted by updated_at fails exactly at the page whose cursor has 2-digit millis.
Results are also non-deterministic across runs for identical params (e.g. limit: 50 + sourceKinds sometimes returns 49 with nextCursor: null, sometimes 50 with a valid cursor), suggesting a race in the state-db listing path.
What is the expected behavior?
thread/list with useStateDbOnly: true should honor limit up to 500 and return all unarchived threads (it works correctly for limit <= 49), and pagination cursors should round-trip. With that fixed, the sidebar should list all unarchived threads under each project again, as it did before ~2026-06-10.
Additional information
- State DB is healthy: 167 threads, 165 unarchived, all with valid
cwdand existing rollout files undersessions/;thread/searchandthread/readwork fine on the same data. - The legacy listing path (
useStateDbOnly: false) returns correct results for the same params, so the regression is isolated to the state-db-only implementation. - Mobile app shows full history (server-side listing), desktop does not — consistent with a local listing bug.
- Happy to provide further traces or run instrumented builds against this CODEX_HOME if useful.
6 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Confirmed the same behavior on macOS with Desktop App
26.609.30741/ bundledcodex-cli 0.140.0-alpha.2.In my case the sidebar was completely empty (not just project sections), and rebuilding
~/.codex/session_index.jsonlfromstate_5.sqlitedid not help.A workaround that restored the sidebar for me was clearing the Desktop App's renderer cache and restarting:
However, as noted above this does not work for everyone, so it is likely just perturbing the renderer into using a different request path rather than fixing the underlying
thread/listregression.I also see this error in logs on every launch, which may be related to the same alpha auth/provider change:
Thanks for confirming on macOS — that rules out anything Windows-specific.
Your cache-clearing workaround is consistent with the root cause described above, and likely explains why it doesn't work for everyone: clearing the renderer caches also wipes the locally cached feature-gate evaluations, so on next launch the expanded-thread-history gate evaluates to its default (off) and the sidebar falls back to the legacy
useStateDbOnly: falsepath — which works. Once the gate cache re-syncs from the server, the gate turns back on and the regression returns. So it perturbs exactly the request path you suspected, rather than fixingthread/list.Regarding the 403 on
/v1/models(api.model.readmissing scope): probably unrelated. The failingthread/list { useStateDbOnly: true, limit >= 50 }call reproduces fully offline against the local SQLite state DB, with no network involved, so the listing regression can't be an auth/scope issue.Follow-up: tested the cache-clearing workaround on Windows (app 26.609.3341.0, same runtime) — it does not restore the sidebar here, in either form:
Cache,Code Cache,GPUCache,Session Storagein both the Electron profile root andweb/Codex/Default) → sidebar still shows "No chats" for every project after restart.Local Storage(which holds the locally cached feature-gate/Statsig state) → same result.So the gate appears to be re-evaluated from the server during startup, before the sidebar first renders — which would explain why the cache workaround is unreliable across machines: it only helps if the renderer happens to fall back to the legacy listing path before the gate state is re-fetched. In other words, there is no reliable local workaround; the fix needs to land in the
thread/listuseStateDbOnlyimplementation (or the expanded-history gate rolled back until it does).I've been experiencing this issue for several days now. The manipulations only helped launch a common flat chat list, but linking threads to a project still hasn't appeared.
I reproduced this on Windows and completed a successful full recovery. The result suggests that, at least in my case, the current application build was functional, but the existing per-user Codex state had become inconsistent.
Initial symptoms
No chats.projectless-thread-idsrestored chat visibility, but only as one flatChatslist without project grouping.Clean-profile test
I created a completely separate Windows user account and installed Codex there.
Under that clean Windows profile:
This showed that the installed application build itself could work correctly and that the problem was specific to the original user's local Codex state.
State verification
Before modifying anything, I backed up the complete
%USERPROFILE%\.codexdirectory and created a consistent SQLite backup.Results from the affected profile:
PRAGMA integrity_check:okSeveral thread working directories used inconsistent path representations, including forms equivalent to:
D:\project/mnt/d/projectC:\mnt\d\projectRecovery procedure
With Codex fully closed:
.codexdirectory and allowed Codex to create a fresh profile.state_5.sqlite;rollout_path;cwdto the real existing Windows path;session_index.jsonlrecord when one existed.electron-saved-workspace-rootsproject-orderprojectless-thread-ids.PRAGMA integrity_checkafter each migration batch.Final result
okThe final restored profile still contains more than 50 active threads and currently works correctly. This may mean that the exact
thread/list limit >= 50regression is no longer active in the current build/environment, while the old local profile remained in an inconsistent state across application updates.Suggested product improvement
Codex Desktop needs a supported Repair / Reindex local history operation that can:
state_5.sqlite;Users should not need to edit SQLite and
.codex-global-state.jsonmanually to recover conversations that are still present on disk.Related: #19873, #27906, #27843. A redacted recovery manifest and recovery script are available for maintainers if needed.