Missing required fields in Responses API input items when using non-Azure endpoints

Resolved 💬 3 comments Opened Feb 19, 2026 by zhuangqh Closed Feb 25, 2026
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

What version of Codex CLI is running?

0.104.0

What subscription do you have?

gptoss

Which model were you using?

gptoss

What platform is your computer?

Darwin 25.3.0 arm64 arm

What terminal emulator and version are you using (if applicable)?

warp

What issue are you seeing?

Bug Description

When Codex sends a multi-turn conversation to a custom/OSS Responses API endpoint
(e.g., vLLM), several required fields are omitted from input items. The same
requests work against the official OpenAI endpoint, which appears to silently
tolerate the missing fields — but any strictly-conforming server will reject them
with a 400 validation error.

Root Cause

In codex-rs/codex-api/src/endpoint/responses.rs, attach_item_ids is guarded
by an Azure-only condition:

if request.store && self.session.provider().is_azure_responses_endpoint() {
    attach_item_ids(&mut body, &request.input);
}

This means id fields are only patched back onto items when targeting an Azure
endpoint. For the default OpenAI endpoint and all OSS endpoints (e.g., vLLM, any
OpenAI-compatible server), the serialization relies on
#[serde(skip_serializing)] on the id field of ResponseItem::Reasoning in
protocol/src/models.rs — and attach_item_ids is never called to restore it.

Additionally, ResponseOutputMessage and ResponseInputMessageItem items sent
in conversation history are missing fields that the OpenAI spec marks as
Required.

Missing fields per item type

| Item type | Role | Missing field | OpenAI spec requirement |
|-------------|-------------------|---------------|---------------------------------------------------------------|
| reasoning | — | id | Required[str] |
| message | assistant | status | Required[Literal["in_progress", "completed", "incomplete"]] |
| message | user / system | id | Required[str] |

What steps can reproduce the bug?

Reproduction

  1. Deploy any OpenAI-compatible Responses API server (e.g., gptoss deployed on vLLM)
  2. Configure Codex to use it: base_url = "http://localhost:8000/v1"
  3. Start a conversation that produces reasoning output or spans multiple turns
  4. On the second turn the request payload will be missing the fields above,

causing the server to return:

400 Bad Request
{
  "error": {
    "message": "N validation errors: {'type': 'string_type', 'loc': ('body', 'input', ..., 'str'), ...}"
  }
}

What is the expected behavior?

Expected Behavior

All input items sent to any Responses API endpoint should include the fields
required by the
OpenAI Responses API spec,
regardless of whether the target is Azure, the official OpenAI endpoint, or a
third-party compatible server.

Additional information

Proposed Fix

Remove the is_azure_responses_endpoint() guard so attach_item_ids runs for
all endpoints:

// codex-rs/codex-api/src/endpoint/responses.rs

// Before
if request.store && self.session.provider().is_azure_responses_endpoint() {
    attach_item_ids(&mut body, &request.input);
}

// After
attach_item_ids(&mut body, &request.input);

Additionally, ensure status: "completed" is always populated on assistant
message items and id is always populated on user/system message items before
serialization.

View original on GitHub ↗

3 Comments

github-actions[bot] contributor · 6 months ago

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

  • #11834
  • #12114

Powered by Codex Action

etraut-openai contributor · 6 months ago

Please report the issue to the maintainers of vLLM.

You can try switching to Ollama or LMStudio, whose responses endpoints work fine with Codex.

brilliantkid87 · 3 days ago

I can still reproduce a closely related issue on Codex CLI 0.149.1 when using a custom provider with wire_api = "responses".

Environment:

  • Codex CLI: 0.149.1
  • Custom Responses API provider
  • Model: deepseek-v4-flash-0731
  • Windows

During a longer session with tool calls, Codex replayed a function_call input item without an id:

{
  "type": "function_call",
  "name": "exec_command",
  "arguments": "{\"cmd\":\"git status --short\"}",
  "call_id": "call_00_ZXyryEe78cXiB6Yxtd2l2704"
}

The custom Responses endpoint rejected the request with HTTP 400:

Invalid JSON data: Failed to deserialize the JSON body into the target type:
input: data did not match any variant of untagged enum ResponseInput

I isolated the request and tested it directly against the provider.

Without function_call.id: HTTP 400

Adding an ID to the exact same function_call:

{
  "type": "function_call",
  "id": "fc_call_00_ZXyryEe78cXiB6Yxtd2l2704",
  "name": "exec_command",
  "arguments": "{\"cmd\":\"git status --short\"}",
  "call_id": "call_00_ZXyryEe78cXiB6Yxtd2l2704"
}

results in:

HTTP 200

I also confirmed this end-to-end by placing a small compatibility proxy between Codex and the provider that performs only this transformation:

if item.type == "function_call" && item.id is missing:
    item.id = "fc_" + item.call_id

With that compatibility patch, the same Codex session continues successfully.

So this appears to still affect custom Responses API providers in 0.149.1, specifically when Codex replays function_call items without an id.