Skip to content

[Bug] Kiro executor does not strip incompatible Anthropic beta fields (thinking, output_config), causing 400 errors #435

@chugzb

Description

@chugzb

Description

When using Claude Code (v2.1.74) with CLIProxyAPI (v6.8.49-plus) and Kiro OAuth provider, intermittent 400 errors occur with the response:

{"message":"Improperly formed request.","reason":null}

The Kiro backend (generateAssistantResponse) returns this error because the request contains Anthropic-specific beta fields that Kiro does not support.

Root Cause

Claude Code sends requests to /v1/messages?beta=true with fields like:

{
  "thinking": {"type": "adaptive"},
  "output_config": {"effort": "medium"},
  ...
}

The kiro_executor.go forwards these fields as-is to the Kiro API, which rejects them with a 400 error.

In contrast, the Codex and Gemini translators already strip incompatible fields (e.g., defer_loading was fixed in v6.8.42). The Kiro executor needs the same treatment.

Fields that need to be stripped

  • thinking (adaptive thinking config)
  • output_config (effort level)
  • context_management
  • defer_loading (tool declarations)

Reproduction

  1. Configure CLIProxyAPI with Kiro OAuth provider
  2. Use Claude Code v2.1.74+ as client
  3. Start a conversation and use tools — after a few exchanges, Claude Code will add thinking and output_config to the request
  4. Kiro backend returns 400

Logs

[kiro_executor.go:1283] kiro: received 400 error (attempt 1/3), body: {"message":"Improperly formed request.","reason":null}
POST "/v1/messages?beta=true"

Request body contains:

"thinking":{"type":"adaptive"},"output_config":{"effort":"medium"},"stream":true

Environment

  • CLIProxyAPI: v6.8.49-0-plus
  • Claude Code: v2.1.74
  • OS: macOS
  • Kiro OAuth provider

Workaround

Currently retrying/starting a new conversation when 400 occurs. Success rate ~80% as not every request includes these fields.

Expected Behavior

kiro_executor.go should strip Anthropic-specific beta fields before forwarding to the Kiro generateAssistantResponse API, similar to how the Codex/Gemini translators handle incompatible fields.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions