Skip to content

[Bug]: Kimi returns 400 when a Codex tool schema has no root object type #228

Closed

Description

@davidste

Summary

I'm using Kimi K3 through OpenCodex in the Codex desktop app. Normal chat and normal tools worked, but the request started returning HTTP 400 as soon as Codex loaded its deferred automation_update tool for a monitor.

The Kimi response was:

Provider error 400: tools.function.parameters.type is required and must be "object"

The automation tool uses a valid JSON Schema with a root oneOf and no explicit root type. OpenCodex forwards that schema unchanged to Kimi's OpenAI-compatible function format. Kimi requires function.parameters.type to be exactly "object", so it rejects the complete request before the model can call the tool.

This is similar to #122, but Kimi fails on the missing root type itself. It is also related to the Anthropic normalization discussed in #75.

Reproduction

  1. Configure the Kimi OAuth provider and start OpenCodex.
  2. Send this minimized request through the local Responses endpoint:
curl http://127.0.0.1:10100/v1/responses \
  -H 'content-type: application/json' \
  --data-binary '{
    "model": "kimi/k3[1m]",
    "input": "Reply exactly OK. Do not call tools.",
    "tool_choice": "auto",
    "stream": false,
    "tools": [{
      "type": "function",
      "name": "schema_probe",
      "description": "Schema compatibility probe.",
      "parameters": {
        "oneOf": [{
          "type": "object",
          "properties": {
            "mode": { "type": "string", "const": "view" }
          },
          "required": ["mode"],
          "additionalProperties": false
        }]
      }
    }]
  }'
  1. Kimi returns HTTP 400 with:
tools.function.parameters.type is required and must be "object"
  1. Add "type": "object" at the root of parameters while preserving the oneOf. The same request returns HTTP 200.

I also replayed the complete current Codex automation_update schema, not only the minimized example. It failed before normalization and returned 200 after normalization.

Root cause

In src/adapters/openai-chat.ts, toolsToChatFormat() passes t.parameters through unchanged for Kimi.

There are already provider-specific schema paths for xAI and Zen, but Kimi currently uses the unmodified path:

const parameters = xaiTarget
  ? normalizeXaiToolParameters(t.parameters)
  : t.parameters;

The Kimi provider is openai-chat with base URL https://api.kimi.com/coding/v1, so the strict root-object requirement needs to be handled in this adapter.

Tested fix

I applied a provider-scoped normalization locally:

  • Detect api.kimi.com.
  • If function parameters are not an object value, replace them with an empty object schema.
  • If the schema does not explicitly have type: "object", add it at the root while preserving oneOf, $defs, descriptions, and the rest of the schema.

After restarting the proxy:

  • Minimized composed-root schema: HTTP 200.
  • Full Codex automation_update schema captured from the failed thread: HTTP 200.
  • Original Kimi thread resumed successfully instead of returning the schema 400.

A shared root-object normalizer for strict provider adapters may be better than another provider-specific helper, especially given #75 and #122.

Logs and screenshots

# Before
kimi/k3[1m] -> HTTP 400
Provider error 400: tools.function.parameters.type is required and must be "object"

# After root-object normalization
kimi/k3[1m] -> HTTP 200
status=completed

Area

Provider adapter

Version

  • Reproduced on @bitkyc08/opencodex@2.7.30
  • I checked 2.7.31 / current main at 304a1eab; the Kimi path in openai-chat.ts is unchanged.

OS

macOS 26.5.2, arm64, Codex Desktop

Config shape

{
  "provider": "kimi",
  "adapter": "openai-chat",
  "baseUrl": "https://api.kimi.com/coding/v1",
  "authMode": "oauth",
  "model": "k3[1m]"
}

Checks

  • I searched existing issues and docs first.
  • I removed secrets, tokens, personal data, and the original workflow details from the reproduction.

Activity

  1. added a commit that references this issue on Jul 22, 2026
    d5b3796
  2. lidge-jun commented on Jul 22, 2026

    @lidge-jun
    Owner

    Fixed by #250, now merged into dev: schemas routed to api.kimi.com now get a guaranteed root type: "object" (preserving oneOf/$defs and sibling fields), which satisfies Kimi's tool-schema validation. Other providers keep the original schema untouched.

    This will ship with the next release from dev. Closing — please reopen if any tool schema still gets a 400 from Kimi after upgrading.

  3. added 2 commits that reference this issue on Sep 17, 2026
    645aef2
    ad149fa
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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions