Codex history thread disappears when initial prompt is stored only as pasted-text attachment
What version of the IDE extension are you using?
26.616.31447
What subscription do you have?
Team
Which IDE are you using?
VS Code
What platform is your computer?
Linux 6.12.91-1-MANJARO x86_64
What issue are you seeing?
A Codex conversation disappeared from both the VS Code Codex extension sidebar history and the Codex TUI history/resume view.
The session was created from a large pasted prompt. Codex converted the prompt into a pasted-text.txt attachment, but the actual first user message body in the JSONL session was empty/near-empty and only referenced the attachment.
The thread still existed on disk in ~/.codex/sessions/..., and it had a row in ~/.codex/state_5.sqlite, but it was hidden from both history surfaces. This made it look like the conversation had vanished completely.
The first user message in the JSONL looked roughly like this:
# Files mentioned by the user:
## You are an LLM coding agent helping implement ...: ~/.codex/attachments/<id>/pasted-text.txt
The attached pasted text file(s) contain the user's request. Read and act on that content.
The actual prompt only existed in:
~/.codex/attachments/<id>/pasted-text.txt
After I manually inserted the real pasted prompt into the first user-message records in the session JSONL, the thread reappeared in history.
This seems like a shared Codex history/indexing issue, not only a VS Code extension rendering issue, because the thread was missing in both VS Code and Codex TUI.
What steps can reproduce the bug?
- Open Codex in VS Code.
- Start a new conversation.
- Paste a large prompt into the composer.
- Let Codex convert the prompt into a pasted-text attachment.
- Submit the request without adding extra text outside the pasted content.
- Let the conversation proceed normally.
- Reload VS Code and/or open Codex TUI history/resume.
- Observe that the thread may be missing from history even though the JSONL session and attachment still exist on disk.
The core failure appears to be that the first user message is treated as empty because the real content is stored in the pasted-text attachment rather than inline in the JSONL user message.
What is the expected behavior?
Attachment-only or pasted-text-backed prompts should still produce a valid visible history entry.
Additional information
Manual recovery steps that fixed it:
- Found the session JSONL in ~/.codex/sessions/....
- Found the real prompt in ~/.codex/attachments/<id>/pasted-text.txt.
- Backed up:
- the JSONL session file
- session_index.jsonl
- state_5.sqlite
- Edited the session JSONL so the first user message records contained the actual pasted prompt:
- response_item with payload.type = "message" and role = "user"
- event_msg with payload.type = "user_message"
- Updated the SQLite row with a non-empty first_user_message, preview, and title.
- Updated session_index.jsonl.
The thread only reappeared after the actual first prompt was restored into the JSONL user-message records. This suggests re-indexing from JSONL can regenerate an empty/invalid first message if the pasted-text attachment is not considered.
10 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
I hit what appears to be the same bug on Codex Desktop in a project thread.
Broken thread ID: 019ef53f-ecff-7111-93dc-e58102afbdc3
Debug/recovery thread ID: 019ef5cb-f94f-7f70-9fdd-748b7680cac4
This was normal usage, not an intentional attachment-only workflow. I pasted a large kickoff prompt, and Codex automatically transformed it into a pasted-text attachment. The thread then disappeared from normal project history/search even though the raw session JSONL and attachment were still present locally.
Local evidence:
Recovery:
This seems to confirm that attachment-only first prompts can leave thread display/index metadata empty, making valid local threads disappear from project history.
I can confirm a very similar reproduction on Windows Codex Desktop.
Environment:
26.623.708220.142.4state_5.sqlite,session_index.jsonl,sessions/**/*.jsonl,attachments/*/pasted-text.txtObserved behavior:
codex resumepicker.~/.codex/sessions.session_index.jsonlstill had entries for the affected thread IDs.state_5.sqlitestill had rows for the affected thread IDs witharchived = 0.Root-cause evidence from local state:
pasted-text.txt.## My request for Codex:was empty.threadstable instate_5.sqlitehad emptypreviewand/orfirst_user_messagefor affected active threads.WHERE preview <> '', so active unarchived threads with empty preview disappear from normal history surfaces.Local recovery that made the threads visible again:
state_5.sqlite,session_index.jsonl, and affectedrollout-*.jsonlfiles.## My request for Codex:in both first-user-message records inside each affected JSONL:response_itemwithpayload.type = "message"androle = "user"event_msgwithpayload.type = "user_message"title,preview, andfirst_user_messageinstate_5.sqlitefor those thread IDs.codex doctor --summaryreported healthy state and thread inventory agreement, and the threads reappeared in the app/search.Expected behavior:
pasted-text.txt.previewis empty, the app should recover a fallback preview/title from attachment metadata,session_index.jsonl, rollout path metadata, or the first attached text file.This affected multiple active local threads, not just one corrupted session.
Confirmed another occurrence, this time while the thread was still actively running in Codex Desktop.
Environment:
cli_version:0.144.6vscode019f8137…ca3bTrigger:
pasted-text.txtattachment.## My request for Codex:was blank.Sanitized local evidence from
state_5.sqlite:Additional observations:
threads.session_index.jsonl.codex://threads/<thread-id>deep link could still open the conversation.first_user_messageandpreviewvalues.This supports the original diagnosis: attachment-only initial prompts can leave display/index metadata empty, and the sidebar can subsequently omit an otherwise valid, unarchived, active thread. A fallback preview derived from the attached pasted text, or at least its attachment label, would prevent the thread from becoming undiscoverable.
Follow-up on this reproduction:
codex://threads/<thread-id>link does not open it; the Desktop renderer displays the link with a generic globe/web treatment instead of routing it to the local thread.This leaves no working in-app discovery path for an active attachment-only thread. The user can confirm that the task is alive from the rollout and external GoalBuddy board, but cannot reopen the conversation from the Desktop sidebar, search, or a rendered deep link.
Confirmed reproduction in the VS Code extension
I can confirm that this defect remains reproducible in the Codex VS Code extension with threads reporting:
Controlled test results
I ran three controlled tests in the same workspace.
1. Ordinary inline-text request
first_user_messagelength:454previewlength:4542. Long paste automatically converted to
pasted-text.txtThe automatically created attachment was submitted without any accompanying inline text.
first_user_messagelength:0previewlength:03. The same attachment with a typed companion message
Before submitting the attachment, I manually added this inline message:
The resulting metadata was:
first_user_messagelength:107previewlength:107---
Attachment-only thread details
The attachment-only thread had the following properties immediately after completing, before VS Code was disconnected or restarted:
The task completed successfully and received a generated title. Its rollout transcript was also present and contained the conversation.
This indicates that the failure occurs while creating the thread’s display or indexing metadata. It is not caused by VS Code closing or reconnecting.
---
VS Code restart test
I separately tested an ordinary inline-text thread using the following sequence:
454characters.The thread remained visible, and both metadata fields still contained their original
454characters.This rules out ordinary VS Code closure, remote disconnection, and workspace reconnection as the trigger in this environment.
---
Reproducible workaround
The following workaround prevents the empty-metadata condition:
pasted-text.txt.For example:
The manually typed companion message is then stored in both
first_user_messageandpreview, preventing the affected thread from being omitted from the sidebar.---
Recovery test
I also recovered a previously hidden thread without modifying its rollout transcript.
After first backing up
state_5.sqlite, I populated only the thread’s emptyfirst_user_messageandpreviewfields using its existing generated title.The result was:
ok.This demonstrates that the conversation itself had not been deleted. Only the metadata used to display or index the thread was missing.
---
Findings
The controlled tests confirm that:
pasted-text.txtattachment.first_user_messageandprevieware left empty.archived = 0.I have observed the same empty-field condition in affected threads created with:
0.145.0-alpha.270.146.0-alpha.30.146.0-alpha.3.1The problem therefore appears to span multiple builds and remains reproducible in
0.146.0-alpha.3.1.---
Privacy note
For privacy and security reasons, I am not uploading:
state_5.sqlitedatabaseThe controlled canary contained only harmless inert padding and reproduced the issue reliably.
Additional VS Code occurrence: hidden but directly resumable thread
I can confirm this issue on another VS Code-originated local thread. It is absent from All chats and from an exact-title search, although its rollout remains intact and a direct
codex resume <session-id>succeeds.Environment rechecked on 2026-07-31
1.130.0(x64)openai.chatgpt 26.727.40816codex-cli 0.146.0-alpha.9.2codex-cli 0.146.0-alpha.3.17.0.0-28-generic(x86_64)codex_vscode/vscode019fb3ed-be2c-7053-8d28-3a36952576d3Observed behavior
Read-only local evidence
The corresponding
threadsrow was inspected using an immutable, read-only SQLite connection; no repair or mutation was performed:The referenced rollout file still exists. All
1,294JSONL records parse successfully, a structuraltask_completeevent is present, and the rollout contains one user-message event despite the SQLite row reportinghas_user_event = 0.During the first second of thread creation, the extension log emitted this warning 33 times:
Likely trigger and reproduction
The trigger is likely attachment-only first-message handling, although I have not reduced the
/goalvariant to a fully deterministic minimal reproduction:/goalrequest through an automatically generated pasted-text attachment, without meaningful inline companion text.In this occurrence, the initial user event is only an attachment placeholder; the substantive request was attachment-backed.
Expected behavior
An active, unarchived thread with a valid rollout and generated title should remain discoverable regardless of whether its first substantive request was inline or stored in a pasted-text attachment. Thread creation or later reindexing should derive safe display metadata from the attachment metadata or generated title, and direct resume should repair missing index metadata where possible.
Actual behavior
The rollout and completed conversation remain usable by direct ID, but the extension excludes the thread from both history and exact-title search because
previewandfirst_user_messageremain empty.Related reports
/goal-first, empty-preview aspect.Privacy
I am not uploading the database, rollout JSONL, pasted prompt, transcript, full logs, home paths, or screenshots. The evidence above contains only structural counts, redacted metadata, and one minimal diagnostic message.
Corroborating Desktop / Remote reproduction
I independently reproduced this attachment-only initial prompt failure in Codex Desktop on Windows. The task history remained recoverable, but empty first-message metadata caused the active task to disappear from the Desktop project/pinned views and from Remote on mobile.
Because the existing task was not visible on the phone, the same work was started again remotely. That created overlapping agent runs against a week-long project and nearly caused damage. This makes the defect a safety issue, not only a history/sidebar issue: Remote should not omit an active task because its initial prompt was stored only in pasted-text.txt, and Codex should warn before starting a duplicate run for the same project when another run may already exist.
Full sanitized corroborating report and proposed safeguards: https://github.com/openai/codex/issues/34446#issuecomment-5142560117
No private transcript, task identifiers, local paths, database data, or repository details are included here.
I can independently confirm this failure mode on Codex Desktop.
A large initial prompt was automatically converted to
pasted-text.txtwith no additional inline text. The active, unarchived thread retained its conversation history, but itsfirst_user_messageandpreviewmetadata were empty. After restarting Codex Desktop, the thread disappeared from the project and pinned views and was also absent from Remote on mobile, even though it could still be opened through its direct thread reference.The practical risk is more serious than lost discoverability: because Remote/mobile made the active task appear absent, the same job was started again against the same repository and linked development environment. This created overlapping agent runs and nearly damaged a week-long project.
This makes the defect a safety issue, not only a history/sidebar issue. Attachment-only tasks should always receive a durable fallback title/preview (for example, from
pasted-text.txtmetadata), and Remote/mobile should not omit an active task solely because inline first-message metadata is empty. It would also be valuable to warn before starting a likely duplicate run for the same project while another run may already be active.Full sanitized corroborating report and proposed safeguards: #34446, especially https://github.com/openai/codex/issues/34446#issuecomment-5142560117
No private transcript, thread IDs, local paths, SQLite contents, or repository-specific details are included here.
I’m testing Codex Rescue
0.1.0a3against cases where the local rollout still exists but normal history discovery fails. Your attachment-only first prompt is a useful boundary because the session is physically present while the history/index projection effectively hides it.Rescue does not mutate
session_index.jsonlor SQLite, and it will not fabricate attachment text that is not present in the rollout. I’d like to see whether it can still discover the session and report the missing/ambiguous boundary safely.If you still have a backup from before the manual repair, would you be willing to try:
Sanitized output only is enough. Please don’t post the raw pasted prompt, attachment, rollout, DBs, credentials, or private paths.
https://github.com/shleder/codex-rescue