Codex App session list can hide sessions whose first user message is an empty diff-comment wrapper

Open 💬 4 comments Opened May 22, 2026 by winoros
💡 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)?

0.133.0

What subscription do you have?

Pro

What platform is your computer?

Linux 6.17.0-22-generic x86_64 x86_64

What issue are you seeing?

A persisted Codex App session can disappear from the normal session list even though the rollout JSONL and the SQLite state DB row both exist.

In my local case, the session had:

  • source = vscode
  • thread_source = user
  • archived = 0
  • model_provider = openai
  • a matching cwd
  • non-empty title / preview in the state DB

However, a normal thread/list call returned no rows for the same filters. The same request returned the session when useStateDbOnly was set to true.

The root cause appears to be the interaction between Codex App's diff-comment wrapper and the filesystem-backed thread/list path:

  1. The first event_msg user message in the rollout was generated from a diff comment wrapper.
  2. The wrapper included ## My request for Codex:, but there was no content after that marker.
  3. rollout/src/list.rs strips everything before USER_MESSAGE_BEGIN when extracting the preview.
  4. Because the marker tail was empty, the first user message produced no preview.
  5. The next actual user message was much later in the rollout, beyond HEAD_RECORD_LIMIT + USER_EVENT_SCAN_LIMIT.
  6. The normal metadata-filtered thread/list path returned the filesystem scan page, where the session did not satisfy summary.preview.is_some(), even though the state DB had a usable title/preview.

What steps can reproduce the bug?

One way to reproduce is to create or capture a Codex App session whose first persisted user message is a diff-comment wrapper like this:

# Diff comments:

## Comment 1
File: /path/to/file
Side: R
Lines: 123
Comment:
some review comment

## My request for Codex:

Then continue the session normally so a later user message has real text, but appears far enough into the rollout that read_head_summary does not scan it.

After the session is persisted:

  1. Verify the rollout JSONL exists under ~/.codex/sessions/....
  2. Verify the row exists in the state DB with a non-empty title/preview.
  3. Call thread/list with normal metadata filters, for example source vscode, provider openai, archived=false, and the matching cwd.
  4. Observe that the session is not returned.
  5. Repeat the same thread/list request with useStateDbOnly=true.
  6. Observe that the session is returned.

In my local probe, the normal response was:

{"data":[],"nextCursor":null,"backwardsCursor":null}

With useStateDbOnly=true, the same session was returned from the state DB.

What is the expected behavior?

The session should appear in the normal session list when it has valid persisted metadata in the state DB, or the preview extractor should find a later non-empty user message instead of treating the empty wrapper tail as the only displayable user input.

More generally, a Codex App-generated diff-comment wrapper with an empty ## My request for Codex: tail should not make an otherwise valid user session undiscoverable.

Additional information

The relevant code paths appear to be:

  • rollout/src/list.rs: read_head_summary, event_msg_preview, and strip_user_message_prefix
  • rollout/src/recorder.rs: metadata-filtered list_threads_with_db_fallback
  • thread-store/src/local/list_threads.rs: normal list path vs. useStateDbOnly

The surprising part is that the DB path knows about the session, but the normal filtered listing still returns the filesystem scan page and drops the DB-only hit.

View original on GitHub ↗

4 Comments

github-actions[bot] contributor · 3 months ago

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

  • #22777

Powered by Codex Action

winoros · 3 months ago

ok, seems that they are the same issue.

GabbeV · 2 months ago

I also hit this when my first message was a pasted file with no further text. Used ChatGPT to narrow down the work around to editing the session rollout file manually by adding a period to the end of the first message. After that the chat once again show up in codex ui and cli.

diegobonacolsi · 1 month ago
I also hit this when my first message was a pasted file with no further text. Used ChatGPT to narrow down the work around to editing the session rollout file manually by adding a period to the end of the first message. After that the chat once again show up in codex ui and cli.

This helped a lot, thanks.

Below is my conclusion drafted with Codex itself.

Root cause: the normal thread/list filesystem scan skipped sessions whose rollout started with an empty ## My request for Codex: wrapper. The threads were still present in SQLite, thread/read and codex resume worked, and thread/list with useStateDbOnly: true returned them correctly.

Workaround: after backing up the rollout JSONL, I changed the empty wrapper to ## My request for Codex:. (added a single period). Both missing threads immediately reappeared in the Codex UI.

This seems most likely when a new thread starts from pasted/attached context without an actual text instruction in the first message.