openai / openai/codex

Missing \call_id\ on injected standalone \ unction_call_output\ also breaks normal thread resume / cross-thread send under third-party Responses providers

Open
#42,067 4 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

app app-server bug custom-model windows-os
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

Summary

With Codex Desktop 26.825.51511 (app-server 0.151.0-alpha.7.2) and a third-party
provider using wire_api = "responses" (DeepSeek), resuming an existing thread or
sending a message to it
fails with:

Failed to deserialize the JSON body into the target type: input: missing field `call_id` at line 1 column ~1605392

This is the same root cause as #41690, but that report only covers the automation
path (codex_app__automation_update). Here it also reproduces during ordinary
thread resume
and cross-thread send (e.g., delegating a task to another thread /
send_message_to_thread), so the impact is broader than automations.

Environment

  • Windows
  • Codex Desktop app build: 26.825.51511
  • Embedded app-server / command runner: 0.151.0-alpha.7.2
  • Model provider: DeepSeek (third-party) via a local relay
  • Config:
    • model_provider = "openai-chat-completions"
    • base_url = "http://127.0.0.1:19100/v1"
    • wire_api = "responses"
    • requires_openai_auth = true
    • model = "deepseek-v4-flash-vision-exp"

Reproduction

  1. Use a third-party Responses provider (DeepSeek).
  2. Open a thread that has accumulated tool calls (function_call / function_call_output).
  3. Send a new message (or delegate a task to it).
  4. The turn fails with missing field call_id.

Evidence

The session rollout records a response_item of type function_call_output that has
id, name, namespace, output, and internal_chat_message_metadata_passthrough
but no call_id:

{"type":"function_call_output","id":"...","name":"...","namespace":"codex_app","output":"...","internal_chat_message_metadata_passthrough":"..."}

This item is written into the session at the moment the thread is resumed (triggered by
the new message). When the app-server assembles the request body for the Responses API,
this standalone output lacking call_id is rejected by the strict third-party
deserializer.

Regression note

This worked on 26.820.71523 (8/30) and started failing after the app updated to
26.825.51511 on 8/31, with the same DeepSeek Responses provider throughout. Both
#41690 and #41799 are also on 26.825.51511.

Requested behavior

  • When injecting a standalone function_call_output (no matching call in the immediate
    turn), the app-server should either synthesize a call_id or normalize it into a
    provider-accepted message before sending to third-party Responses providers.
  • Alternatively, expose a provider capability/feature flag so strict Responses providers
    receive a compatible tool-output shape.

Related

  • #41690 (automation + DeepSeek + missing call_id)
  • #41799 (macOS + Azure + missing call_id)
  • #37786, #30523 (root oneOf tool schema for codex_app tools)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in the app-server code that assembles resumed-thread and cross-thread requests for the Responses API, tracing how standalone function_call_output response_items from session rollouts are serialized. Reproduce with the strict third-party Responses provider described here, then verify that resumed and cross-thread turns no longer fail because call_id is missing.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
api, backend-api-design
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.