CLI /goal persists pasted text as inline file instructions that /goal edit does not reconstruct
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
Version and environment
Codex CLI 0.153.4 on native Windows x64 (OS build 10.0.26200), originally observed in an Orca embedded terminal. The Goal persistence code also remains present in main snapshot 3d3df0a0cad5d3d8d3340b633787e9dd304ea463. Model/subscription are not material to this TUI persistence path; no inference result is used as evidence here. A doctor report is not included.
Actual behavior
When a /goal draft contains long pasted text, the saved objective replaces each paste placeholder with an inline instruction:
pasted text file: <CODEX_HOME>/attachments/<id>/pasted-text-1.txt. Read this file before continuing.
Surrounding typed text stays inline. If a paste occurs in the middle of a sentence, the reference is embedded directly in that sentence. Source inspection shows that /goal edit does not restore these individual files into the original text; this edit behavior has not been independently reproduced interactively. The internal file-reference representation therefore becomes the user-editable goal.
This is not a claim that the payload files are missing or the original bytes have been deleted. In the observed case, all three files existed and contained 4,660, 2,885, and 3,130 characters. A read-only inspection confirmed that the saved objective itself contained three reference instructions; it was not merely a terminal rendering artifact. Private goal contents, attachment paths, and session identifiers are omitted.
Proposed minimal reproduction
- In the CLI composer, type
/goal Prefix. - Paste more than 1,000 characters, for example
"sample paragraph "repeated 100 times, so the composer creates a paste placeholder. - Type
suffix, submit the goal, and then open/goal edit. - The saved/editable objective contains
Prefix pasted text file: ... Read this file before continuing. suffixrather than the original paragraph.
The sequence above follows the current code path; it has not been rerun as a complete interactive acceptance test on a newly built CLI. The persisted real-world example and the existing upstream test establish the storage transformation independently of that proposed manual reproduction.
Source-level cause
ChatComposer::handle_pastekeeps pastes over 1,000 characters inpending_pastesand inserts display placeholders.materialize_goal_draftcomputes expanded text for an emptiness check but then materializes each pending paste separately and replaces its placeholder with the reference instruction.- In the same file,
objective_text_for_editrecognizes only the whole-objectivegoal-objective.mdreference. It does not reassemble inlinepasted-text-N.txtreferences, even after loading a whole-objective file. - The upstream test
set_thread_goal_draft_materializes_long_objective_and_confirms_before_pasteexplicitly expectsUse pasted text file: ...for aUse <placeholder>draft. The existing test explicitly expects this transformation; the reported defect is the failure to preserve the editable prose across save/edit.
Windows timing-based paste detection can make one physical paste become multiple placeholders, but that is not required to trigger this Goal bug. Even one pending paste is sufficient. Windows paste latency is tracked in #14099; this report concerns Goal persistence, rather than the desktop-app attachment UX in #25144 or #25346.
Expected behavior and suggested fix
Saving and reopening a Goal should preserve the objective text, apart from documented normalization. Internal input chunk boundaries should not determine how many files or inline instructions appear in the editable goal.
Expand the active pending-paste placeholders into the complete objective first, then apply the existing 4,000-character inline-objective limit. If externalization is needed, write the complete objective to the existing single goal-objective.md format, which the editor already knows how to read. Preserve/remap non-paste text-element spans for images using the existing expansion helper.
Suggested regression cases: mixed Korean text and multiple paste placeholders; one oversized objective saved and reopened as a single document; image placeholders after pasted spans; stale/deleted placeholders; whitespace-only pasted text.
For pre-existing goals, avoid blindly interpreting reference-looking prose as metadata or making one missing attachment prevent the entire goal from being edited. A legacy recovery design should be considered separately.
Validation limits
Source inspection, the existing upstream test, saved-state/file inspection, and independent code review support the diagnosis. Regression tests for the suggested change and full CLI integration remain outstanding. The full build was stopped because of local resource pressure. No fixed binary, complete test-suite pass, or user acceptance is claimed.
Submitting the analysis as an issue in accordance with the current contributing policy, which does not accept external PRs.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with codex-rs/tui/src/goal_files.rs, especially materialize_goal_draft and objective_text_for_edit, then inspect paste handling in codex-rs/tui/src/bottom_pane/chat_composer.rs. Run the existing set_thread_goal_draft_materializes_long_objective_and_confirms_before_paste test in codex-rs/tui/src/app/tests.rs. Done means saving and reopening a goal preserves mixed prose and paste content, with regression coverage for the listed placeholder cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100