gpt-5.6-sol/terra/luna hardcode use_responses_lite / multi_agent_version, causing 400s on Azure (and likely any non-ChatGPT-backend) model_provider

Open 💬 9 comments Opened Jul 9, 2026 by tianwei-mo
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

What version of Codex CLI is running?

codex-cli 0.144.0 (codex --version)

What subscription do you have?

Azure OpenAI, API-key auth (env_key in model_providers.azure). No ChatGPT account/subscription involved in this setup.

Which model were you using?

gpt-5.6-sol (also affects gpt-5.6-terra and gpt-5.6-luna per the bundled catalog — see root cause below)

What platform is your computer?

Linux 6.17.0-1019-aws x86_64 x86_64

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

VS Code integrated terminal (TERM_PROGRAM=vscode)

Codex doctor report

{
  "schemaVersion": 1,
  "overallStatus": "ok",
  "codexVersion": "0.144.0",
  "checks": {
    "auth.credentials": {
      "status": "ok",
      "summary": "auth is provided by the active model provider",
      "details": {
        "auth storage mode": "File",
        "model provider requires OpenAI auth": "false",
        "provider auth env var": "AZURE_OPENAI_KEY (present)"
      }
    },
    "config.load": {
      "status": "ok",
      "summary": "config loaded",
      "details": {
        "model": "gpt-5.6-sol",
        "model provider": "azure"
      }
    },
    "network.provider_reachability": {
      "status": "ok",
      "summary": "active provider endpoints are reachable over HTTP",
      "details": {
        "azure API base URL": "https://<redacted>.cognitiveservices.azure.com/openai/<redacted> reachable (HTTP 404)",
        "reachability mode": "provider auth"
      }
    }
  }
}

(Trimmed to the relevant checks; full report available on request.)

What issue are you seeing?

Two distinct 400s from the Azure endpoint, in sequence (the second only surfaces once the first is worked around):

1. Responses-Lite transport rejected:

{
  "error": {
    "message": "X-OpenAI-Internal-Codex-Responses-Lite only supports function tools, custom tools, and client-executed tool search.",
    "type": "invalid_request_error",
    "param": "tools",
    "code": "unsupported_value"
  }
}

2. After locally forcing use_responses_lite: false (see workaround below), a second failure surfaces:

{
  "error": {
    "message": "Invalid Value: 'tools'. Namespace 'collaboration' is reserved for encrypted tool use by this model.",
    "type": "invalid_request_error",
    "param": "tools",
    "code": null
  }
}

Both errors come from the provider (Azure), not from Codex — Codex is constructing a request shape the provider was never told to expect, and the provider correctly rejects it. Reproduced independently by a second engineer on the same endpoint/key, so this isn't a one-off local misconfiguration.

Root cause: codex-rs/models-manager/models.json is compiled directly into the Codex binary via include_str! (codex-rs/models-manager/src/lib.rs):

pub fn bundled_models_response() -> ... {
    serde_json::from_str(include_str!("../models.json"))
}

As of the models.json update that landed today (commit 3380969a29, "Update models.json (#31684)"), the three new gpt-5.6-* entries ship with:

"tool_mode": "code_mode_only",
"multi_agent_version": "v2",   // v1 for gpt-5.6-luna
"use_responses_lite": true,

These flags are unconditional per-model constants — nothing in codex-rs/core/src/client.rs gates them on the active provider:

add_responses_lite_header(&mut extra_headers, model_info.use_responses_lite);

For providers that are not the Codex/ChatGPT-hosted backend, codex-rs/models-manager/src/manager.rs::should_refresh_models() returns false:

async fn should_refresh_models(&self) -> bool {
    self.endpoint_client.uses_codex_backend().await || self.endpoint_client.has_command_auth()
}

so these providers never fetch a remote catalog and never get a chance to override these flags — they run with the bundled, ChatGPT-backend-shaped metadata as-is. There's already a provider/auth signal available elsewhere in the codebase for exactly this kind of gating (e.g. AuthManager::current_auth_uses_codex_backend, used to filter the model picker by auth mode) — it just isn't consulted before deciding to send X-OpenAI-Internal-Codex-Responses-Lite or the collaboration tool namespace.

Both X-OpenAI-Internal-Codex-Responses-Lite and the collaboration reserved tool namespace read as internal transport/session-state optimizations specific to the OpenAI-hosted Codex backend (compact tool wire format, multi-agent session state) — not general Responses-API capabilities that third-party-hosted deployments of the same model would be expected to implement.

Verified workaround: model_catalog_json (documented as "Optional path to a JSON model catalog (applied on startup only)") lets a StaticModelsManager fully replace the bundled catalog (codex-rs/model-provider/src/provider.rs::models_manager()). Setting "use_responses_lite": false and "multi_agent_version": null for the three gpt-5.6-* entries in a local catalog file, then pointing model_catalog_json at it in config.toml, resolves both errors — verified with plain chat and real tool calls (codex exec "Run the shell command ...") succeeding end-to-end against Azure. This is a local mitigation, not a fix — it will drift out of sync the next time models.json is updated upstream.

What steps can reproduce the bug?

codex exec -m gpt-5.6-sol --skip-git-repo-check "Reply with exactly: OK"

With model_provider = "azure" configured against an Azure OpenAI deployment named gpt-5.6-sol, wire_api = "responses", API-key auth (no ChatGPT sign-in).

What is the expected behavior?

gpt-5.6-sol should work against any configured model_provider the same way gpt-5.5 and gpt-5.4 currently do, or Codex should not send ChatGPT-backend-only request shapes (Responses-Lite header, collaboration tool namespace) to providers that never advertised support for them.

Suggested fix: gate use_responses_lite (and other ChatGPT-backend-only behavior baked into ModelInfo, e.g. multi_agent_version, tool_mode: code_mode_only) on whether the active provider/auth actually talks to the Codex/ChatGPT-hosted backend — the same signal already used for model-picker filtering (AuthManager::current_auth_uses_codex_backend / endpoint_client.uses_codex_backend()) — rather than applying them unconditionally per model slug regardless of model_provider.

Additional information

This looks related to, but distinct from, the existing cluster of "gpt-5.5 routed into Responses-Lite" reports, which are all reported from ChatGPT-account sign-in flows (unexpected server-side routing): #31150, #30403, #30238, #30912, #31705, #31717.

This report is filed from a plain API-key / custom model_provider (Azure) setup with no ChatGPT account involved, which points at the same flag (use_responses_lite) but a different root cause: the bundled catalog is applied unconditionally to all providers, not just ChatGPT-backend ones. Also possibly related to #31843 (gpt-5.6 gets no tools in read-only sandbox), which may share the same "gpt-5.6 metadata wasn't validated against non-default configurations before shipping" theme.

Suggested labels: azure, custom-model, CLI.

View original on GitHub ↗

9 Comments

github-actions[bot] contributor · 11 days ago

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

  • #31875
  • #31870
  • #31864

Powered by Codex Action

Soorma718 · 11 days ago

We are seeing the same issue on our side as well.

Environment:

``text
Codex CLI: 0.144.0
Platform: Linux / WSL
Provider: Azure OpenAI / Foundry
Auth: API key via env_key
Model/deployment: gpt-5.6-sol
``

Our Azure deployment itself is healthy. Direct calls to the Azure Responses endpoint work:

``text
POST https://<resource>.cognitiveservices.azure.com/openai/responses?api-version=2025-04-01-preview
model: gpt-5.6-sol
``

A minimal direct payload succeeds:

``json
{
"model": "gpt-5.6-sol",
"input": "Reply exactly: OK",
"max_output_tokens": 64,
"store": false,
"reasoning": {
"effort": "high",
"summary": "auto"
}
}
``

We also confirmed Azure accepts these reasoning efforts for gpt-5.6-sol:

``text
none works
low works
medium works
high works
xhigh works
max works
ultra rejected by Azure
``

So the deployment/key/endpoint are not the problem.

Codex direct to Azure fails with the same first error:

``json
{
"error": {
"message": "X-OpenAI-Internal-Codex-Responses-Lite only supports function tools, custom tools, and client-executed tool search.",
"type": "invalid_request_error",
"param": "tools",
"code": "unsupported_value"
}
}
``

We also independently reproduced the second error after bypassing/stripping Responses-Lite behavior. Codex sends an additional_tools developer item
containing a namespace tool named collaboration:

``json
{
"type": "namespace",
"name": "collaboration",
"description": "Tools for spawning and managing sub-agents."
}
``

Azure rejects that with:

``json
{
"error": {
"message": "Invalid Value: 'tools'. Namespace 'collaboration' is reserved for encrypted tool use by this model.",
"type": "invalid_request_error",
"param": "tools",
"code": null
}
}
``

We verified a temporary workaround in two ways:

  1. Local proxy workaround:
  • strip Codex-only/internal headers,
  • remove the collaboration namespace from additional_tools,
  • forward to Azure /openai/responses?api-version=2025-04-01-preview.

With that, plain chat and shell tool use work against Azure gpt-5.6-sol.

  1. Cleaner model catalog workaround:
  • override the model catalog so gpt-5.6-sol has:

``json
"use_responses_lite": false
``

  • and avoid Azure’s reserved collaboration namespace by setting:

``toml
[features.multi_agent_v2]
tool_namespace = "agents"
``

This also gets plain chat and normal shell tool calls working directly against Azure without the proxy.

That seems to confirm the root cause described above: bundled gpt-5.6-* model metadata is being applied unconditionally to Azure/custom providers, even
though the use_responses_lite and collaboration behavior appear specific to the OpenAI-hosted Codex/ChatGPT backend.

Expected behavior would be for Codex to gate use_responses_lite, multi_agent_version, tool_mode: code_mode_only, and/or the collaboration namespace on
whether the active provider actually supports the Codex backend behavior, rather than applying those flags solely based on model slug.

For Azure/custom providers, gpt-5.6-sol should behave like gpt-5.5/gpt-5.4 unless the provider explicitly advertises support for the Codex-specific
Responses-Lite/collaboration transport.

ignatremizov · 11 days ago

In addition you can also stay on multi_agent v1:

# ~/.codex/config.toml
model_catalog_json = "~/.codex/models-v1.json"

[features]
multi_agent = true
multi_agent_v2 = false

Then create ~/.codex/models-v1.json from the current model catalog and change only these fields:

"slug": "gpt-5.6-sol",
"multi_agent_version": "v1"

and optionally:

"slug": "gpt-5.6-terra",
"multi_agent_version": "v1"

You can also optionally instead set version as "null" for all three Sol, Terra, and Luna, so that multi-agent schema version is defined by features config, not model catalog, but that's up to you.

JanekRzodki · 11 days ago

azure deployments are having some trouble today.
I have gpt-5.3-codex deployed on CLI and vs code extension.
Whenever I prompt it it returns error: imagegen deployment must be provided through header: x-ms-oai-image-generation-deployment

It's like it wants to use or needs to have an image generation tool deployed for simple non related to image generation prompts.

I opened an issue but no answer yet: https://github.com/openai/codex/issues/31775

Nauxie · 11 days ago

I reproduced this against Azure OpenAI and have a scoped patch ready on current main.

Proposed behavior:

  • Add internal provider capabilities for Responses-Lite and the reserved collaboration tool namespace.
  • Disable those two capabilities only when the existing is_azure_responses_provider(...) detector matches.
  • Derive one effective Responses-Lite value from model metadata plus provider capability, and use it consistently for HTTP turns, compact requests, WebSocket metadata, reasoning context, tool placement, and parallel tool calls.
  • Keep multi-agent v2 available on Azure, but expose its functions without the reserved collaboration namespace.
  • Preserve existing OpenAI, ordinary custom-provider, and Bedrock behavior.

Coverage includes:

  • Azure turn and compact requests use standard Responses formatting with no internal Lite header.
  • Azure multi-agent tools remain available as flat functions.
  • Existing Responses-Lite WebSocket behavior remains unchanged.
  • Existing custom-provider and Bedrock capability behavior remains unchanged.

Verification:

  • just test -p codex-model-provider: 55 passed.
  • Focused codex-core regressions: 3 passed.
  • Responses-Lite and tool-plan slice: 39 passed.
  • just fix -p codex-model-provider, just fix -p codex-core, and just fmt pass.

Patch: https://github.com/Nauxie/codex/commit/e5b78f8

The contribution guide says external PRs require an explicit invitation, so I have not opened one. If this approach matches the intended provider boundary, would a maintainer be willing to invite the PR?

kr0mka · 10 days ago

Slightly unrelated, but this might actually have something to do with use_responses_lite: has anyone here also noticed prompt-caching issues with GPT-5.6 deployments on Azure OpenAI / Foundry?

I originally noticed this while using Codex CLI against Azure with the forementioned use_responses_lite fix. GPT-5.6 Sol sessions consistently showed cached_input_tokens = 0, even across consecutive requests in the same long-running thread. GPT-5.5 on the same setup showed normal cache hits.

I then reproduced it independently with direct PowerShell requests to the Azure /openai/v1/responses endpoint, so it does not appear to be only a Codex telemetry issue.

The test generates a fresh deterministic prompt and cache key, then sends the exact same request twice. The same Azure resource, endpoint, authentication, request structure and test method were used for each deployed model.

Clean comparison with approximately 13,200 input tokens:

| Model | Request 1 cached | Request 2 cached |
|---|---:|---:|
| GPT-5.5 | 0 | 13,056 of 13,181 (~99%) |
| GPT-5.6 Luna | 0 | 0 |
| GPT-5.6 Sol | 0 | 0 |

I also tested a larger prompt of approximately 171,500 input tokens:

| Model | Request 1 cached | Request 2 cached |
|---|---:|---:|
| GPT-5.5 | 0 | 167,680 (~98%) |
| GPT-5.6 Luna | 0 | 0 |
| GPT-5.6 Sol | 0 | 0 |

I additionally tried:

  • redeploying GPT-5.6 Luna without a custom deployment alias;
  • sending the legacy prompt_cache_retention: "24h" field for GPT-5.6 Sol.

Neither changed the result. I have not tested GPT-5.6 Terra yet.

Considering responses_lite header isn't working with Azure deployments I wasn't able to check if adding that would actually make a cache hit.

From the Codex source, prompt_cache_key appears to be sent regardless of use_responses_lite, but Responses-Lite also changes the request structure and adds the internal header.

Has anyone observed normal cached_tokens or cache_write_tokens reporting with GPT-5.6 Sol, Terra or Luna on Azure?

Could the OpenAI-hosted Responses-Lite path be handling cache writes, sticky routing or cache affinity differently in a way that is not currently available through Azure?

zzh506767805 · 9 days ago

Same root cause reproduced with the ChatGPT desktop app (macOS, app version 26.707.41301, bundled codex 0.144.0-alpha.4) using a custom Azure provider (wire_api = "responses", API key auth). A few data points not yet mentioned in this thread:

  1. [features] overrides in config.toml are not a reliable mitigation in the desktop app. With multi_agent_v2 = false and tool_search = false set (and the app fully restarted), new threads still sent both the {"type":"namespace","name":"collaboration"} tool and a {"type":"tool_search","execution":"client"} tool — server-driven feature flags appear to take precedence over config.toml [features] in the app.
  1. Azure also rejects tool_search with "execution": "client" under the Lite header, even though the error text claims client-executed tool search is supported (400 invalid_request_error, param: "tools", code: "unsupported_value"). So a provider-gated fix may want to cover tool_search placement as well, not just the collaboration namespace.
  1. The model_catalog_json workaround requires complete ModelInfo entries. A minimal catalog containing only slug plus the overridden fields fails at startup with:

``
failed to resolve feature override precedence: failed to parse model_catalog_json path
... as JSON: missing field display_name
``

In the desktop app this parse failure also prevents the thread list/history from loading, which looks like data loss to the user (the rollout files are intact). What worked: extracting the full embedded catalog from the bundled binary (the {"models": [...]} blob), then setting "use_responses_lite": false, "multi_agent_version": null, "tool_mode": null for the gpt-5.6-* entries. Partial/merge semantics for model_catalog_json would make this workaround much less brittle.

  1. Minor: with the catalog override applied, "prefer_websockets": true causes several failed reconnect attempts per turn against Azure before falling back to HTTP; also setting "prefer_websockets": false for these models avoids the extra latency.

With the full-catalog override, plain chat and tool calls work end-to-end against Azure gpt-5.6-sol. +1 for gating these model-metadata behaviors on the active provider rather than the model slug.

ignatremizov · 9 days ago

@zzh506767805 yeah, sorry, I should have been more clear that it needs a full copy of the base models.json

kenny7869 · 8 days ago

It looks like Azure has resolved this issue, as I haven't encountered the same problem again today(2026-07-13 09:56 UTC+8).