codex - 💡(How to fix) Fix Codex Desktop silently hides project conversations outside the global recent-50 window [2 comments, 3 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openai/codex#21128Fetched 2026-05-06 06:26:22
View on GitHub
Comments
2
Participants
3
Timeline
7
Reactions
2
Author
Timeline (top)
labeled ×3commented ×2cross-referenced ×1subscribed ×1

Codex Desktop currently makes older project conversations effectively disappear from the UI once they fall outside the global recent conversation window. This is not an edge case and it is not just cosmetic: it makes the Desktop app unreliable as a working memory for real projects.

In my daily use, any thread that has not been updated for about a week becomes impossible to find in the Desktop UI. After investigating locally, this is not because the data is deleted. The local session files and SQLite rows are still present. The problem is that Desktop appears to preload only a global recent set of conversations, then groups/searches only that already-loaded subset.

This is a serious UX regression. Users are led to believe their project history has been deleted or lost, while the data is still on disk and visible through lower-level storage/CLI paths. Please prioritize a real fix rather than requiring users to patch bundles, touch rollout mtimes, pin hidden threads, or manually query SQLite.

Root Cause

In my daily use, any thread that has not been updated for about a week becomes impossible to find in the Desktop UI. After investigating locally, this is not because the data is deleted. The local session files and SQLite rows are still present. The problem is that Desktop appears to preload only a global recent set of conversations, then groups/searches only that already-loaded subset.

Fix Action

Fix / Workaround

This is a serious UX regression. Users are led to believe their project history has been deleted or lost, while the data is still on disk and visible through lower-level storage/CLI paths. Please prioritize a real fix rather than requiring users to patch bundles, touch rollout mtimes, pin hidden threads, or manually query SQLite.

  1. When expanding/opening a project, query all local threads for that project/workspace root (cwd) with pagination.
  2. Sidebar search should query all persisted local threads, not only recentConversationIds already loaded into memory.
  3. The UI should clearly distinguish "no chats" from "older chats not loaded yet". The current behavior is misleading.
  4. The recent window size should either be much larger or configurable as a temporary mitigation, but increasing 50 to another fixed small number is not the real fix.
  5. Add a regression test with >50 local conversations across multiple projects where one project has no conversations in the global top 50 but still has valid local history.

Code Example

~/.codex/sessions: 2014 rollout JSONL files
~/.codex/session_index.jsonl: 564 entries
~/.codex/state_5.sqlite: 1250 active thread rows

---

where archived = 0
  and agent_role is null
  and source in ('vscode', 'cli')

---

890 direct active local conversations
50 updated within the last 7 days
840 older than 7 days

---

rank 50: 2026-04-28 13:13:24 local time
rank 51: 2026-04-27 20:12:58 local time

---

Project A: 447 active local conversations, 0 in top 50, newest rank 56 -> not findable in Desktop project UI
Project B: 24 active local conversations, 0 in top 50, newest rank 257 -> not findable in Desktop project UI
Project C: 8 active local conversations, 0 in top 50, newest rank 67 -> not findable in Desktop project UI

---

thread_count_loaded_recent: 54

---

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

loadNextThreadListPage(...) {
  ...
  await this.listRecentThreads({ limit: 50, cursor: this.nextCursor })
  ...
}

searchThreads(...) {
  // searches only this.conversationIds, i.e. the loaded recent subset
}

listRecentThreads(...) {
  return this.requestClient.sendRequest("thread/list", {
    limit,
    cursor,
    sortKey: this.sortKey,
    modelProviders: null,
    archived: false,
    sourceKinds: ...
  })
}
RAW_BUFFERClick to expand / collapse

Summary

Codex Desktop currently makes older project conversations effectively disappear from the UI once they fall outside the global recent conversation window. This is not an edge case and it is not just cosmetic: it makes the Desktop app unreliable as a working memory for real projects.

In my daily use, any thread that has not been updated for about a week becomes impossible to find in the Desktop UI. After investigating locally, this is not because the data is deleted. The local session files and SQLite rows are still present. The problem is that Desktop appears to preload only a global recent set of conversations, then groups/searches only that already-loaded subset.

This is a serious UX regression. Users are led to believe their project history has been deleted or lost, while the data is still on disk and visible through lower-level storage/CLI paths. Please prioritize a real fix rather than requiring users to patch bundles, touch rollout mtimes, pin hidden threads, or manually query SQLite.

Environment

  • Platform: macOS, arm64
  • Codex Desktop observed: 26.429.30905 (CFBundleVersion 2345)
  • CLI observed: codex-cli 0.125.0
  • Date reproduced: 2026-05-05

I also inspected another local Codex app bundle (26.422.21459) and found the same recent-list behavior, so this does not appear to be a one-off local install issue.

Local evidence

Local persisted data is present:

~/.codex/sessions: 2014 rollout JSONL files
~/.codex/session_index.jsonl: 564 entries
~/.codex/state_5.sqlite: 1250 active thread rows

Using a conservative filter for human-visible direct conversations:

where archived = 0
  and agent_role is null
  and source in ('vscode', 'cli')

I get:

890 direct active local conversations
50 updated within the last 7 days
840 older than 7 days

The cutoff is extremely telling:

rank 50: 2026-04-28 13:13:24 local time
rank 51: 2026-04-27 20:12:58 local time

So the issue looks like "older than a week" only because my last week of usage produced exactly 50 newer conversations. Once a conversation drops from rank 50 to rank 51, it disappears from the Desktop project UI/search even though it still exists locally.

Example project-level impact with private paths redacted:

Project A: 447 active local conversations, 0 in top 50, newest rank 56 -> not findable in Desktop project UI
Project B: 24 active local conversations, 0 in top 50, newest rank 257 -> not findable in Desktop project UI
Project C: 8 active local conversations, 0 in top 50, newest rank 67 -> not findable in Desktop project UI

Telemetry from the Desktop app also matches this failure mode:

thread_count_loaded_recent: 54

while the local database has hundreds of active direct conversations. The extra 4 appear to be pinned/currently loaded threads on top of the hardcoded recent 50.

Code-path evidence from the Desktop bundle

The Desktop app bundle contains this recent-loader behavior:

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

loadNextThreadListPage(...) {
  ...
  await this.listRecentThreads({ limit: 50, cursor: this.nextCursor })
  ...
}

searchThreads(...) {
  // searches only this.conversationIds, i.e. the loaded recent subset
}

listRecentThreads(...) {
  return this.requestClient.sendRequest("thread/list", {
    limit,
    cursor,
    sortKey: this.sortKey,
    modelProviders: null,
    archived: false,
    sourceKinds: ...
  })
}

This means the project sidebar is effectively grouping a global recent subset, not loading the actual history for each project/workspace.

Expected behavior

The Desktop UI must not hide valid local project conversations just because they are outside the latest 50 global conversations.

Expected behavior should be:

  1. When expanding/opening a project, query all local threads for that project/workspace root (cwd) with pagination.
  2. Sidebar search should query all persisted local threads, not only recentConversationIds already loaded into memory.
  3. The UI should clearly distinguish "no chats" from "older chats not loaded yet". The current behavior is misleading.
  4. The recent window size should either be much larger or configurable as a temporary mitigation, but increasing 50 to another fixed small number is not the real fix.
  5. Add a regression test with >50 local conversations across multiple projects where one project has no conversations in the global top 50 but still has valid local history.

Related issues / prior reports

This appears related to, and still reproducible despite, earlier reports:

  • #15060
  • #14751
  • #17540
  • #18364

Please do not treat this as solved while Desktop still depends on a global recent-50 preload for project history visibility. This bug seriously damages trust in the app because it makes real, persisted work history appear to vanish.

extent analysis

TL;DR

The issue can be mitigated by modifying the listRecentThreads function to load all local threads for a project/workspace root with pagination, rather than relying on a global recent conversation window.

Guidance

  • Investigate increasing the limit parameter in the listRecentThreads function to a larger number or making it configurable to temporarily mitigate the issue.
  • Modify the searchThreads function to query all persisted local threads, not just the recentConversationIds already loaded into memory.
  • Implement pagination when loading threads for a project/workspace root to prevent loading all threads at once.
  • Add a clear distinction in the UI between "no chats" and "older chats not loaded yet" to prevent misleading users.

Example

// Example of how to modify the listRecentThreads function to load all local threads with pagination
async function listAllThreads(projectRoot, limit, cursor) {
  const threads = await this.requestClient.sendRequest("thread/list", {
    limit,
    cursor,
    sortKey: this.sortKey,
    modelProviders: null,
    archived: false,
    sourceKinds: ...,
    projectRoot, // Add projectRoot parameter to filter threads by project
  });
  return threads;
}

Notes

The provided code snippet is just an example and may need to be adapted to the actual implementation. The issue is complex and requires a thorough understanding of the Codex Desktop app's architecture and functionality.

Recommendation

Apply a workaround by increasing the limit parameter in the listRecentThreads function to a larger number, such as 200 or 500, to temporarily mitigate the issue. This will allow more conversations to be loaded and visible in the UI, but a permanent fix will require modifying the app's architecture to load all local threads for a project/workspace root with pagination.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

The Desktop UI must not hide valid local project conversations just because they are outside the latest 50 global conversations.

Expected behavior should be:

  1. When expanding/opening a project, query all local threads for that project/workspace root (cwd) with pagination.
  2. Sidebar search should query all persisted local threads, not only recentConversationIds already loaded into memory.
  3. The UI should clearly distinguish "no chats" from "older chats not loaded yet". The current behavior is misleading.
  4. The recent window size should either be much larger or configurable as a temporary mitigation, but increasing 50 to another fixed small number is not the real fix.
  5. Add a regression test with >50 local conversations across multiple projects where one project has no conversations in the global top 50 but still has valid local history.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

codex - 💡(How to fix) Fix Codex Desktop silently hides project conversations outside the global recent-50 window [2 comments, 3 participants]