Responses Lite sends an empty description for the default functions namespace, rejected by Azure OpenAI

Open 💬 3 comments Opened Aug 11, 2026 by wukong121
💡 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.147.0

What subscription do you have?

API/custom model provider using Azure OpenAI through LiteLLM; not tied to a ChatGPT subscription.

Which model were you using?

gpt-5.6-sol

What platform is your computer?

Windows 11, arm64

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

PowerShell

Codex doctor report

{
  "status": "not available for the affected Codex build"
}

What issue are you seeing?

When Responses Lite is enabled for a model and the provider supports namespace
tools, Codex groups normal function/custom tools into an additional_tools
item under the default functions namespace.

Codex serializes this namespace with an empty description:

{
  "type": "namespace",
  "name": "functions",
  "description": "",
  "tools": [...]
}

Azure OpenAI's Responses API rejects the request before inference:

HTTP 400
Invalid 'input[0].tools[0].description': empty string

Removing the field also fails:

Missing required parameter: 'input[0].tools[0].description'.

Changing only the description to a non-empty value, such as
"Built-in function tools", makes the same request succeed with HTTP 200.

This issue is conditional: it only occurs when the selected model has
use_responses_lite=true. Normal Responses requests do not reproduce it.

What steps can reproduce the bug?

1. Configure a Responses-compatible custom provider backed by Azure OpenAI.
2. Select a model whose metadata has `use_responses_lite=true`.
3. Ensure namespace tools are supported and start a normal Codex turn containing
   function tools.
4. Inspect the generated Responses request.
5. Observe that the first `additional_tools` item contains a `functions`
   namespace whose `description` is `""`.
6. Send the request to Azure OpenAI and observe HTTP 400.

Minimal relevant request shape:

```json
{
  "model": "affected-model",
  "input": [
    {
      "type": "additional_tools",
      "role": "developer",
      "tools": [
        {
          "type": "namespace",
          "name": "functions",
          "description": "",
          "tools": [
            {
              "type": "function",
              "name": "lookup_order",
              "description": "Look up an order",
              "parameters": {
                "type": "object",
                "properties": {}
              }
            }
          ]
        }
      ]
    },
    {
      "type": "message",
      "role": "user",
      "content": [
        {
          "type": "input_text",
          "text": "Reply only: ok."
        }
      ]
    }
  ]
}

### What is the expected behavior?

```markdown
Codex should not emit an empty required namespace description.

Possible fixes include:

- use a non-empty default such as `"Built-in function tools"` for the
  `functions` namespace;
- normalize empty descriptions for non-OpenAI/Azure providers; or
- disable Responses Lite namespace serialization when the configured provider
  cannot accept that wire format.

Existing non-empty namespace descriptions should remain unchanged.

Additional information

Current source explicitly creates and preserves this empty value:

  • codex-rs/tools/src/responses_api.rs:

default_namespace_description("functions") returns String::new().

  • codex-rs/tools/src/tool_spec_tests.rs:

responses_lite_preserves_empty_functions_namespace_description asserts that
the serialized description equals "".

  • codex-rs/core/tests/suite/responses_lite.rs also asserts the empty

description in the generated additional_tools request.

Relevant source:

https://github.com/openai/codex/blob/main/codex-rs/tools/src/responses_api.rs

https://github.com/openai/codex/blob/main/codex-rs/tools/src/tool_spec.rs

https://github.com/openai/codex/blob/main/codex-rs/tools/src/tool_spec_tests.rs

The failure was validated through LiteLLM 1.95.0 against Azure OpenAI.
LiteLLM forwards the nested namespace description unchanged.

Transport does not appear to be the root cause: the invalid payload is produced
by Responses Lite serialization and can affect HTTP or WebSocket transports.

View original on GitHub ↗

3 Comments

github-actions[bot] contributor · 17 days ago

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

  • #37380
  • #37422
  • #37692
  • #37487
  • #37675

Powered by Codex Action

jyokotori · 17 days ago

I don't understand why such a simple issue is taking this long to fix. It's quite frustrating.😡

jdcodes1 · 9 days ago

Pinpointed: the empty string is deliberate and one function deep. default_namespace_description special-cases the default namespace to return String::new() — every other namespace gets "Tools in the {name} namespace." (https://github.com/openai/codex/blob/1f41cc5d92/codex-rs/tools/src/responses_api.rs#L64-L70). OpenAI's backend tolerates the empty description; Azure's Responses validator requires it non-empty and requires the field's presence, which is why both your variants 400.

Simplest fix is dropping the special case so functions also gets a real sentence — the field is model-visible prose, and a generic "Standard function tools." is strictly more informative than "". If there's a reason the OpenAI backend prefers the empty string for the default namespace (prompt-length golf?), the alternative is making it provider-aware at serialization, but that seems like complexity for no benefit given a two-word description. Either way this is a one-line change plus a fixture update.