[CLI][custom provider] Type-invalid item_ reasoning IDs survive replay validation and OpenAI expects rs_
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.5k
- PR merge metrics
- PR metrics pending
Description
What version of Codex CLI is running?
codex-cli 0.148.0-alpha.9 (Codex Desktop 26.810.7004.0, Windows x64)
What subscription do you have?
ChatGPT subscription through Codex Desktop. The defect is in request serialization and reproduces independently of the subscription tier.
Which model were you using?
Responses API models. The failure is independent of the selected model.
What platform is your computer?
Windows 11 x64
What terminal emulator and version are you using (if applicable)?
Codex Desktop; PowerShell 7 was used for source-level verification.
Codex doctor report
not included: the report contains unrelated local configuration; the source-level reproduction and regression tests below isolate the failure
What issue are you seeing?
When a local task contains response items produced by a custom Responses-compatible provider and the task is subsequently continued using OpenAI authentication, Codex can send the custom provider's generic item_... ID back to the OpenAI Responses API.
OpenAI rejects the request:
[ApiIdParam] [input[292].id] [invalid_id_prefix]
Invalid 'input[292].id': 'item_REDACTED'. Expected an ID that begins with 'rs'.
The problem is in ModelClient::prepare_response_items_for_request() in codex-rs/core/src/client.rs. It currently checks only:
if item.id().is_some_and(|id| !id.is_prefixed()) {
item.set_id(None);
}
ResponseItemId::is_prefixed() accepts any non-empty prefix and suffix, so item_foreign-reasoning is considered valid. However, the API validates IDs by response-item type: reasoning requires rs_, messages require msg_, function calls require fc_, and so on.
The same implementation remains present on current main at commit 9ded177ce7c1c0bd2047f902936c177612ab3434 (checked 2026-08-16).
This is not the UUID/local-message case in #32282 or #33395, and it is not the Azure store=false persistence issue in #35739. Here the ID is syntactically prefixed, but its prefix belongs to no valid API item type.
What steps can reproduce the bug?
-
Configure a custom Responses-compatible provider.
-
Start a task and let the provider return persisted response items such as:
{ "type": "reasoning", "id": "item_foreign-reasoning", "summary": [], "encrypted_content": "foreign-ciphertext" }A custom provider may also return message or function-call items with generic
item_...IDs. -
Preserve the same local task history and switch the active route/authentication to OpenAI.
-
Continue the task with another user message.
-
prepare_response_items_for_request()retainsitem_foreign-reasoningbecauseis_prefixed()returns true. -
The OpenAI Responses API rejects the request with
invalid_id_prefix, expectingrs_.
A deterministic source-level regression fixture can append the foreign reasoning item above, plus a message and function call using item_..., to the existing HTTP and WebSocket client request tests. Both transports reproduce the incorrect serialization before the fix.
What is the expected behavior?
Outgoing response item IDs should be checked against the prefix required by their concrete ResponseItem type, not merely checked for the presence of any prefix.
For portable items such as messages and function calls, Codex should omit a type-invalid ID from the request copy while preserving content, call_id, and outputs. For foreign reasoning or compaction items that carry provider-specific opaque state, Codex should omit the item from the cross-provider request rather than replaying undecryptable ciphertext.
The persisted local prompt/history should remain unchanged.
Additional information
A validated fix against the exact rust-v0.148.0-alpha.9 tag does the following:
- Adds
ResponseItemId::is_prefixed_with(expected_prefix). - Uses
ResponseItem::id_prefix()during outbound request preparation. - Removes reasoning/compaction items whose IDs have a type-invalid prefix from the request copy.
- Clears type-invalid IDs from portable message/tool items while preserving their content and linkage fields.
- Restores original IDs after WebSocket request serialization so in-memory and persisted prompt state are not mutated.
Focused regression tests passed for:
- HTTP Responses request serialization;
- Responses-over-WebSocket serialization and prompt non-mutation;
- type-specific prefix validation.
The observed task history, prompts, tool output, and encrypted fields were not attached to this report. The synthetic values above are sufficient to reproduce the defect without exposing user data or credentials.
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 in codex-rs/core/src/client.rs at ModelClient::prepare_response_items_for_request(), then inspect ResponseItemId and ResponseItem prefix handling. Run or extend the existing HTTP and WebSocket client request serialization tests with the foreign reasoning, message, and function-call IDs; done means type-invalid IDs are handled correctly, content is preserved where applicable, and persisted prompt state is unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- api, backend-api-design, testing
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 66/100