Codex Desktop chats disappear from sidebar after restart when the first request is supplied as a pasted-text attachment
What version of the Codex App are you using (From “About Codex” dialog)?
26.715.7063.0
What subscription do you have?
Pro
What platform is your computer?
Microsoft Windows NT 10.0.26200.0 x64
What issue are you seeing?
Summary
Codex chats created with a large initial request supplied through an attached pasted-text.txt file can disappear from the sidebar after the desktop app is fully closed and reopened.
The transcript is not deleted. The rollout, SQLite thread row, session-index records, title, archive state, and project assignment remain intact. However, Codex leaves the SQLite first_user_message and preview fields empty. The sidebar’s visible-thread indexes require preview <> '', so the chat is omitted when the sidebar reloads after restart.
This has happened repeatedly and is reproducible with attachment-based initial prompts.
Latest affected chat
- Title: Phase 1E-B3B2
- Thread ID: 019f8262-5ee8-7a00-bede-a4b083facf6b
- Thread type: normal user thread
- Project: local project peptide-tracker-native
- State: active, not archived
- Rollout: present and readable
- Session-index records: present, including the renamed title
- Project assignment: correct in both global-state files
- SQLite integrity: ok
- Foreign-key violations: 0
- first_user_message length: 0
- preview length: 0
What steps can reproduce the bug?
Reproduction steps
- Open a registered local Codex project in the Windows desktop app.
- Create a new Codex chat.
- Make the initial request a large pasted request that Codex represents as an attached pasted-text.txt file.
- Allow the chat to run normally.
- Rename it to a short title.
- Fully close the ChatGPT/Codex window and exit it from the system tray.
- Reopen the desktop app.
- Select the same project and check both project-grouped and Chronological sidebar views.
What is the expected behavior?
Expected behavior
The chat should remain visible after restart because:
- Its rollout transcript exists.
- Its SQLite thread row exists.
- It is active and classified as a user thread.
- Its session-index records exist.
- Its project assignment is valid.
- Its title and working directory were persisted.
Additional information
Actual behavior
The chat disappears from the sidebar after restart.
Read-only inspection shows that Codex created all other metadata but failed to populate:
first_user_message = ""
preview = ""
The current SQLite database contains sidebar-visible partial indexes equivalent to:
WHERE preview <> ''
Consequently, the otherwise-valid chat is excluded when the sidebar is rebuilt from persistent storage.
The database backfill state is already marked complete, so reopening Codex does not repair the missing fields.
Repeated pattern
This is not an isolated thread. Three recovered chats previously had the same condition:
- Valid rollout
- Valid SQLite row
- Valid session-index metadata
- Correct project assignment
- Empty first_user_message
- Empty preview
- Missing from the sidebar
Those chats also began with requests represented through pasted-text attachment wrappers. Populating only the two missing fields restored their visibility across multiple full restarts.
Simple chats whose first message was ordinary inline text received nonempty preview fields and persisted normally.
This suggests that the first-message metadata extraction path does not correctly handle an initial user message represented as an attachment wrapper, possibly when injected plugin or environment context precedes it.
Relevant rollout structure
For the latest affected chat:
- The rollout header contains the correct thread ID and working directory.
- The first recorded user-role item contains injected plugin context.
- The next genuine user item references the attached pasted-text.txt.
- Codex processes the request successfully and records subsequent responses.
- No corresponding metadata error is reported in the logs.
- The thread title, session index, and project assignment are still written successfully.
This appears to be a silent metadata-ingestion failure rather than transcript loss or SQLite corruption.
Impact
- Active work appears lost after an application restart.
- The user cannot resume the chat through the normal sidebar.
- Chronological view and Archived Chats do not help because the row fails the database visibility predicate.
- Local database recovery is required to make the chat visible again.
- Repeating that recovery is risky and should not be necessary for newly created chats.
Temporary workaround
Starting a chat with a short ordinary inline message, waiting for the first response, and sending the large attached request in a second turn appears likely to avoid the problem. This is only a workaround and has not been established as an official solution.
Requested investigation
Please investigate the Codex Desktop path that derives and persists first_user_message and preview for a new thread when its initial genuine request is represented by a pasted-text attachment.
In particular, please verify:
- Whether injected plugin/environment user-role items interfere with first-message selection.
- Whether attachment-wrapper messages are intentionally excluded without a fallback to their referenced pasted text.
- Why title/index/project metadata succeeds while both visibility fields remain empty.
- Why completed backfill state prevents later correction.
- Whether the sidebar should exclude otherwise-valid user threads solely because preview is empty.
Please also provide a supported, version-aware way to rebuild thread visibility metadata from intact rollout files. A supported repair or diagnostic function would be much safer than direct SQLite intervention.
I can provide sanitized counts, schemas, index definitions, relevant timestamps, and short log excerpts if needed. I will not send authentication files or full private transcript contents.
15 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
This also causes an issue where active sessions don’t appear correctly when using the remote feature in the phone app. More details from Codex are included below:
Yes—there are two related but distinct problems.
preview: 75 charactersfirst_user_message: 75 characterspreview: 11,934 charactersfirst_user_message: 0 characterspreview: 2,734 charactersfirst_user_message: 2,734 characterssession_index.jsonlrename.The evidenced explanation is:
first_user_message.All three rollout headers otherwise match:
Codex Desktop,source=vscode,thread_source=user, the same CLI version, repository, branch, model provider, and normalized working directory. The Remote connection itself is healthy and connected; no logs show either missing thread ID being requested, rejected, or dropped.OpenAI’s documentation says Remote should expose “the same projects [and] chats” on the connected host. Your restored tasks violating that expectation supports treating this as a product defect, not intended behavior. [OpenAI Remote connections documentation](https://learn.chatgpt.com/docs/remote-connections)
I would not alter B2D’s SQLite fields speculatively. The appropriate next bounded repair investigation would be:
first_user_messagefrom its preserved first request, while retaining the existing preview.No files, databases, processes, or application state were changed during this inspection.
Comment written by GPT 5.6 after fixing the issue on my machine
"""
Confirmed independently on macOS 26.1 using Codex Desktop 26.715.72359 (build 5718), CLI 0.145.0-alpha.18.
A completed thread created from a large initial prompt represented as pasted-text.txt disappeared from the sidebar.
Read-only inspection confirms:
thread ID: 019f72ba-5cae-7320-a17f-1493b218ba0a
title, CWD, project association, and rollout file are intact
thread is active and archived = 0
first_user_message length = 0
preview length = 0
the thread can still be opened directly by ID, but normal thread listing omits it
This matches the reported preview <> '' visibility failure exactly and confirms the defect is cross-platform.
"""
Additional Windows reproduction: missing Remote/mobile entry caused a dangerous duplicate run
I independently reproduced this exact defect in Codex Desktop on Windows with a local project thread whose initial substantive request was supplied only through the automatically generated
pasted-text.txtattachment wrapper.Sanitized evidence
threadsrow remained active:archived = 0,archived_at = NULL, with the correct title, CWD, and project directory.first_user_messagelength =0,previewlength =0.local_thread_catalog.first_user_message,preview, or the catalog entry.Safety impact beyond sidebar visibility
The affected task also failed to appear through Remote on the user's phone. Because the user could not see the existing task remotely, they reasonably assumed it was unavailable and started the same task again from the phone. This created overlapping agent activity against the same repository and linked development environment. The project represented approximately one week of work and was nearly damaged by the duplicate run.
This makes the bug more than a cosmetic history problem: a missing catalog entry can cause users to launch duplicate high-impact work against the same project while the original task still exists or is still running.
Requested behavior
pasted-text.txt(or its attachment label) rather than omitting the task entirely.previeworfirst_user_messageis empty.I can provide the affected thread ID and additional sanitized catalog/SQLite diagnostics privately if maintainers need them. I am intentionally not posting the private transcript, database, attachment contents, or repository details publicly.
Additional reproduction: Windows Desktop over SSH to Linux, five consecutive affected root threads
I reproduced this on Windows Codex/ChatGPT Desktop connected over SSH to a Linux host, with Codex CLI 0.146.0 and a shared remote
CODEX_HOME.Reproduction pattern
Within one remote project, five newly created Desktop root threads were affected consecutively:
source = vscodethread_source = usermodel_provider = openaiarchived = 0threadsrow existssession_index.jsonlcontains the thread IDfirst_user_message = ''preview = ''The threads remained usable during the active Desktop process, but disappeared after Desktop/app-server restart. They were then missing from both the Desktop sidebar and the normal CLI
resumepicker.No transcript loss occurred. Direct reads/resume by exact thread ID still worked.
App-server evidence
Using the app-server WebSocket protocol for read-only inspection:
thread/readsucceeded for the affected thread.thread/listwithuseStateDbOnly = truestill omitted the newest affected thread.first_user_messageandpreviewwere returned normally.This shows the omission is not caused by a missing rollout, missing SQLite row, missing session-index entry, archive state, CWD mismatch, source kind, or provider mismatch. The active thread becomes undiscoverable because its durable display metadata is empty.
Relevant rollout structure
The affected rollout begins with:
<recommended_plugins> ...);The request executes normally and the title is generated, but
first_user_messageandpreviewremain empty. This suggests the first-message metadata extraction path may select or skip the injected user-role record and then fail to fall back to the genuine attachment-backed request.Additional observed behavior
One previously affected thread became discoverable again after it was resumed by exact ID and received a later ordinary inline user message. After that, its
first_user_messageandpreviewwere populated and it remained visible.Requested safeguards
previeworfirst_user_messageis empty.All diagnostics were read-only. No rollout, SQLite row, session index, or transcript content was modified. I can provide sanitized thread IDs and schema/query details privately if useful.
Still reproducible on Windows package 26.803.5235.0 / app-server CLI 0.147.0-alpha.6.5
I independently reproduced the same attachment-only metadata failure in a local Windows project after a Codex Desktop update and restart.
The affected task completed before the update under CLI
0.147.0-alpha.1.2. Windows then replaced package26.730.8199.0with26.803.5235.0; the current bundled app-server reports CLI0.147.0-alpha.6.5. After restart, the task disappeared from the normal task list, but remained directly readable by its exact thread ID.Sanitized read-only evidence
threadsrow still exists with a non-empty generated title, correct CWD/project association, andarchived = 0.first_user_messagelength =0.previewlength =0.nameis null, while the generatedtitleis non-empty.thread/readsucceeds.thread/listwithuseStateDbOnly = trueomits the thread.The initial genuine user item has the standard attachment-wrapper shape: it references a generated
pasted-text.txt, states that the attachment contains the request, and has no inline content after## My request for Codex:.Current app-server query evidence
Printable SQL embedded in the currently installed
codex.exeshows the list query applying:The binary also contains a repair path equivalent to:
That repair cannot help this case because both
previewandfirst_user_messageare empty, even though the generated title and intact rollout provide safe fallback metadata.This narrows the failure to the current app-server inventory/list path rather than transcript deletion, archive state, lost project mapping, or frontend-only rendering. The update/restart exposed the problem because the rebuilt list excludes the otherwise-valid row.
Requested fix
preview = ''.I am intentionally omitting the full thread ID, local username/path, repository name, database, rollout contents, and attached request. I can provide additional sanitized offsets, counts, and version evidence if maintainers need it.
The empty
first_user_message/previewcase is a strong discovery mismatch: the rollout, SQLite row, session-index entries, title, and project assignment all survive, but the sidebar predicate hides the thread after restart.I’m testing Codex Rescue against this exact boundary. It scans local rollouts independently and does not modify SQLite,
session_index.jsonl, or the source transcript. It cannot rebuild the Desktop preview fields, but it should help confirm that the hidden session is durable and structurally inspectable.If one affected chat still exists, could you run:
pipx install codex-rescue==0.1.0a3codex-rescue sessionscodex-rescue doctor --latestSanitized output is sufficient—please don’t publish raw rollouts, pasted attachments, databases, prompts, project content, paths, or secrets.
https://github.com/shleder/codex-rescue
@shleder Thanks. I confirmed that at least one local rollout associated with a Desktop thread matching the #34446 empty
first_user_message/previewboundary is still present, and tested Codex Rescue 0.1.0a3 against it.I used the hash-matched PyPI wheel without a global install. After reviewing the invoked source paths, I ran only
lightweight_scananddoctor_session, supplying the selected rollout path directly; I did not run salvage or use--latest. Those paths contain no network operation or Codex-state write operation. Doctor did perform read-only Git inspection of the rollout's recorded CWD.Sanitized result:
A separate read-only structural check confirmed, without publishing any values, that the selected rollout's session-metadata ID matched its SQLite thread ID, a matching session-index entry was present, the attachment-wrapper shape was present, and recorded assistant output survived.
Interpretation: the bounded scanner found no malformed tail or unfinished tool call in its sampled windows and returned no prompt preview. Doctor completed its full parse with no finding recognized by 0.1.0a3.
HEALTHYhere is the tool-defined result; it does not prove semantic completeness or repair of the Desktop sidebar fields.Because I supplied the rollout path directly, this confirms only that the file was present and structurally parseable at test time. It does not establish that
codex-rescue sessionswould enumerate the hidden thread.I am sharing only status and boolean fields. No local session or thread IDs, timestamps, paths/CWD values, repository or project names, Git refs or SHA values, prompts, attachment contents, raw rollouts, raw database rows/files, or secrets are included here.
@Motoharu-Kataoka Thanks — this is exactly the kind of real-world validation I was looking for.
One small follow-up would help close the discovery question: could you run only
codex-rescue sessionsand check whether the affected hidden Desktop thread appears in the output?
No need to run
salvage, and please keep the same privacy boundary — I only need a yes/no (or sanitized matching status), not the thread ID, rollout path, prompts, database contents, project names, or other local data.The reason this matters: your direct-path test already confirms the rollout is structurally parseable and untouched. If
sessionsalso discovers it independently, that would validate a useful recovery/discovery case where Desktop visibility diverges from the durable local rollout.@shleder I ran the 0.1.0a3
sessionsCLI entry point with its default options only. It completed successfully, but the selected affected hidden Desktop thread did not appear in the returned set.Important caveat: 0.1.0a3 defaults to the 20 most recently modified rollouts. Therefore this negative result is inconclusive for independent discovery: it shows only that the affected thread was not surfaced by the default command, not that the scanner cannot discover it beyond the default limit.
I captured the output locally and discarded it after comparing the returned summaries against the already-known affected rollout. I am not publishing IDs, paths/CWD values, prompts, repository names, database contents, or raw output. No salvage was run.
If you want a bounded follow-up that distinguishes the 20-item cutoff from discovery behavior, please provide the exact command or limit.
@Motoharu-Kataoka Thanks — that caveat is exactly what I wanted to separate.
Could you run one bounded follow-up with a larger discovery window:
codex-rescue sessions --limit 1000 --jsonPlease compare locally against the already-known affected rollout and reply with only whether the hidden thread appears (
yes/no). No need to paste the command output, IDs, paths/CWD values, prompts, repository names, database contents, or other local data. No salvage needed.If it appears, the earlier miss was only the default 20-item cutoff. If it still does not appear within 1000, that would be useful evidence of a real discovery gap in 0.1.0a3 rather than just ranking/limit behavior.
@shleder No — the already-known affected hidden Desktop thread did not appear in
codex-rescue sessions --limit 1000 --json.Additional independent Windows reproduction on Desktop 26.810.7004.0
I reproduced the same attachment-backed metadata failure on Windows 10 Pro 22H2 (build 19045).
01a009fe-0b67-73a2-9723-02cc6f557261source=vscode,thread_source=user)The initial substantive request was represented only by the generated
pasted-text.txtattachment wrapper; the inline section after “My request for Codex” was empty. The task completed successfully and its full rollout/final answer remain intact.Read-only verification:
archived = 0archived_at IS NULLlength(first_user_message) = 0length(preview) = 0thread/readby exact ID succeeds and returns the full completed transcript.This matches the
preview <> ''discovery failure described in the issue. It also confirms that the defect still reproduces on the newer 26.810.7004.0 Windows Desktop package and that direct reopening does not heal the empty metadata.No transcript text, attachment contents, project files, local paths, database files, or authentication data are included here.
Great diagnosis — you've already found the mechanism: the rollout, SQLite row, session-index records, title, and project assignment are all intact, but
first_user_messageandprevieware empty, and the sidebar's visible-thread query filters onpreview <> ''. So the chat isn't lost; it's invisible because a derived display field was never populated when the first request came in as an attachment instead of inline text.That's a projection gap, not data loss — the attachment-based first prompt path skips the code that backfills preview/first_user_message into the thread row. The repair is to re-derive those two fields from the rollout (the first user turn is right there) and write them back, which is exactly the kind of reconciliation a supported reindex should do.
Full disclosure: I maintain codex-rescue (https://github.com/shleder/codex-rescue).
codex-rescue diff --latestreconciles rollout vs SQLite vs session_index read-only and flags exactly this kind of field-level divergence — present on disk, empty in the projection — so you can confirm the chat is fully recoverable and produce the evidence that the preview backfill is the missing step. It never writes to the state DB, but it gives you the precise reconciliation report.Your hidden-thread tests are preserved: recursive discovery now covers nested rollouts beyond the old default window, and read-only inventory reports
SIDEBAR_METADATA_EMPTYwhen both discovery fields are blank.Migration update: active Codex Rescue development has moved to Vetto: https://github.com/shleder/vetto. The standalone
shleder/codex-rescuerepository remains public as compatibility history. User installation is nownpm install --global @shleddy/vetto@next, with recovery undervetto rescue. The boundary remains read-only/copy-only and does not modify session JSONL or vendor SQLite. The newest diagnostic changes are merged into Vettomainand will be included in a later npm alpha; no source install is requested.