Skip to content

[Responses] Codex task-input envelopes are rejected by translated adapters #3735

Description

@yrlan-montagnier

Client or integration

Codex App

Provider or upstream service

Translated Responses adapters, reproduced with Kiro

OpenCodex version

2.44.0 / af344a2

Endpoint or capability

POST /v1/responses, Codex task coordination

Current behaviour

Codex task coordination can add a result-shaped external input item to the destination task. The observed envelope has type function_call_output, non-empty id, name, and namespace fields, a representable output, and no call_id field. It represents input supplied by another task rather than the result of a tool call made in the destination task.

The common Responses parser currently treats this envelope as a standard tool result. The translated-adapter guard added by #3471 then correctly sees a missing tool identity and returns HTTP 400 before calling the upstream adapter. This prevents Codex from creating or resuming tasks through translated adapters.

Expected behaviour

Only the complete external task-input envelope described above should be converted to user input before adapter translation. Standard function_call_output or custom_tool_call_output items without a non-empty call_id must continue returning HTTP 400, as deliberately implemented by #3471. Items with call_id remain tool results, and incomplete or malformed external envelopes must also remain invalid.

Minimal redacted request or reproduction

Submit a Responses request through a translated adapter with this item in input:

{
  "type": "function_call_output",
  "id": "fco_redacted",
  "name": "send_message_to_thread",
  "namespace": "codex_app",
  "output": "<redacted external task input>"
}

The destination task fails before the provider is called.

Actual response or error

HTTP 400
tool result requires a non-empty string call_id

Upstream documentation

OpenAI Responses API reference: https://platform.openai.com/docs/api-reference/responses/create

The public Responses contract uses call_id to associate actual function tool outputs with calls. No public specification was found for Codex App's inter-task input envelope; that envelope is a concrete Codex App client requirement observed during task creation, follow-up messaging, and task resumption.

Suggested mapping or implementation notes

Preserve the translated-adapter guard from #3471. Before producing common parser messages, recognize only a function_call_output that has no call_id property, has non-empty string id, name, and namespace fields, and has representable output content. Convert that narrowly identified external item to user input, preserving its supported content exactly and without adding an orphan-tool marker such as [tool output for unknown call].

Do not match specific tool names, codex_app, XML tags, or ID prefixes. Do not repair custom_tool_call_output items, items with call_id: "", incomplete provenance, or malformed output content. Negative tests should keep all of those cases on the existing HTTP 400 path. Passthrough and routed compaction behavior must remain unchanged because they use the raw request body.

Additional context and attachments

Related: #3259 and merged PR #3471. The same follow-up report was previously opened as #3732 and closed only because it did not use a recognized issue template.

The initial broad repair was rejected during local review because it would have reversed #3471. The narrowed implementation above was validated with 127 parser and compaction-routing tests, 160 passthrough tests, typecheck, and git diff --check. After restarting the proxy on the local fix, live Codex checks covered task creation, a real exec call, a follow-up after deleting the exec input file, and a same-directory fork. The source task retained values from its earlier tool result, and the fork reproduced all three markers from inherited history together with the source-thread delegation envelope. Archive/unarchive and resuming the originally affected task were also exercised. The broad changed-test suite was not rerun because a previous run exhausted system memory and the Linux kernel terminated Chromium; affected suites were run independently.

Checks

  • I searched existing provider and compatibility issues.
  • The request and response were redacted.
  • The expected behaviour is based on an upstream specification or a concrete client requirement.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    providerProvider adapters, OpenAI-compat presets, upstream API quirksprovider-compatibilityProvider compatibility reportstoolstool_calls, MCP, web-search / sidecar tools

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions