Skip to content

[Bug] Responses adapter drops client User-Agent, breaking Codex-specific provider compatibility #4699

Description

@RailyW

Client or integration

Codex CLI

Provider or upstream service

Volcengine Ark (火山方舟), and other Responses-compatible providers that use the caller's User-Agent to select Codex-specific compatibility handling.

OpenCodex version

Source inspection: dev at cc182a4. The affected user's installed OpenCodex version has not been collected; their upstream log shows Bun/1.4.0.

Endpoint or capability

OpenAI Responses-compatible requests (/v1/responses or the provider's equivalent Responses endpoint).

Current behaviour

OpenCodex drops the original client's User-Agent while building the upstream Responses request. Without an explicit provider header override, a Bun fetch can consequently send its default User-Agent, such as Bun/1.4.0.

Some Responses-compatible providers, including Volcengine Ark in the reported deployment, use User-Agent to recognize Codex requests and enable client-specific compatibility handling. Losing that identity prevents the compatibility handling from being selected and causes requests that depend on it to fail.

The Responses adapter creates a fresh header map. API-key mode adds Content-Type, Authorization, and provider.headers, but does not copy the incoming User-Agent. The OAuth forward-header allowlist also omits User-Agent.

Expected behaviour

Preserve the actual incoming User-Agent on Responses upstream requests when the provider has not explicitly configured a User-Agent. Treat configured header names case-insensitively and keep the provider's explicit override authoritative. If the caller sends no User-Agent, do not invent a Codex identity.

Minimal redacted request or reproduction

  1. Configure an API-key provider using the openai-responses adapter, with no User-Agent in provider.headers.
  2. Send a Codex request through OpenCodex to that provider, carrying the client's normal User-Agent.
  3. Compare the incoming User-Agent with the outgoing header at a controlled upstream receiver.
  4. The incoming identity is absent from the adapter's built request; the Bun transport can supply Bun/ instead.
  5. With an upstream that selects Codex compatibility by User-Agent, observe that the Codex compatibility path is no longer selected.

This can be regression-tested against a local HTTP receiver without provider credentials. A provider-backed reproduction has not yet been run as part of this report.

Actual response or error

Redacted diagnostic evidence supplied by the reporter:

{"upstream_request_headers":{"user_agent":"Bun/1.4.0"}}

The reported consequence is a provider compatibility error. The exact provider status code and response body are not available, so this report does not attribute a specific error payload to Ark.

Upstream documentation

No public specification for Ark's User-Agent-based compatibility selection is supplied with this report; that requirement is based on the reported deployment behavior.

OpenCodex source: https://github.com/lidge-jun/opencodex/blob/cc182a40526a1d87cf5b4b7949fdc6979e70747f/src/adapters/openai-responses/passthrough.ts

Bun documents its default fetch User-Agent: https://bun.sh/docs/runtime/networking/fetch#debugging

Suggested mapping or implementation notes

Copy only the incoming User-Agent as a fallback in the Responses adapter. Preserve explicit provider overrides regardless of header-name casing, without expanding credential or arbitrary-header forwarding. Cover API-key and forward modes, custom overrides, missing UA, and the header actually received over HTTP.

Additional context and attachments

Related: #1751 discussed adding an OpenCodex-specific UA and was declined because providers depend on the upstream client's fingerprint. This report requests preservation of the caller's existing identity rather than a new product identity.

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

    account-poolOAuth, credentials, Codex pool, quota, failover, plansproviderProvider adapters, OpenAI-compat presets, upstream API quirksprovider-compatibilityProvider compatibility reports

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions