Skip to content

Kiro rejects Codex requests with permissive parallel_tool_calls #2308

Closed

Description

@yrlan-montagnier

Client or integration

Codex CLI (also observed through Codex App with WSL as its backend), version 0.149.0.

Provider or upstream service

Kiro

OpenCodex version

2.29.0

Endpoint or capability

POST /v1/responses — function tools and the parallel_tool_calls request hint

Current behaviour

Codex sends a normal Responses request containing parallel_tool_calls: true. OpenCodex parses this into options.parallelToolCalls === true, then the Kiro adapter rejects the request locally with HTTP 400 before dispatching it upstream:

Kiro does not support parallel tool calls

This happens even though the routed Kiro catalog row advertises supports_parallel_tool_calls: false. That catalog metadata does not reliably suppress the request-level hint in Codex.

Expected behaviour

The Kiro adapter should accept the request and continue translating tools on Kiro's serialized wire. In the Responses contract, parallel_tool_calls: true permits parallel calls; it does not require the upstream transport to implement a corresponding request flag or produce parallel calls.

Kiro's translated request has no parallel-tool-call field, so OpenCodex can safely ignore this hint while retaining serialized Kiro execution.

Minimal redacted request or reproduction

curl -i http://127.0.0.1:10100/v1/responses \
  -H 'content-type: application/json' \
  -H 'authorization: Bearer <REDACTED>' \
  --data '{
    "model": "kiro/claude-haiku-4.5",
    "input": "test",
    "stream": true,
    "parallel_tool_calls": true,
    "tools": [{
      "type": "function",
      "name": "bash",
      "description": "Run a shell command",
      "parameters": {"type": "object"}
    }]
  }'

The same request shape is emitted by Codex CLI/App 0.149.0 during an ordinary tool-enabled turn.

Actual response or error

HTTP/1.1 400 Bad Request

Kiro does not support parallel tool calls

Upstream documentation

OpenAI Responses API reference for parallel_tool_calls: https://platform.openai.com/docs/api-reference/responses/create#responses_create-parallel_tool_calls

There is no public Kiro wire specification for this exact field. The concrete integration requirement is also supported by Codex commit openai/codex@86b1123, which removes supports_parallel_tool_calls from ModelInfo/the bundled catalog and sets parallel_tool_calls: true for regular and remote-compaction prompts (while preserving the Responses Lite exception).

Suggested mapping or implementation notes

Remove only the Kiro capability validation that throws when options.parallelToolCalls === true. Do not add a parallel field to the Kiro wire. Keep all other Kiro capability checks unchanged.

A focused regression can parse the Codex-shaped request above, assert that parallelToolCalls remains true, build the Kiro request successfully, and verify that the translated tool catalog is still present.

Additional context and attachments

This is not caused by WSL or a bad local catalog path. The Kiro catalog value is correct; the incompatibility is the adapter's overly strict interpretation of a permissive client hint.

Codex 0.148.0 and 0.149.0 source inspection showed ordinary prompts can send parallel_tool_calls: true. The linked later Codex commit makes the direction explicit by removing the model capability metadata entirely.

Related but not duplicate: #1650 concerns forcing parallelToolCalls=false for OpenAI Chat providers.

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

  1. added
    providerProvider adapters, OpenAI-compat presets, upstream API quirks
    toolstool_calls, MCP, web-search / sidecar tools
    on Aug 21, 2026
  2. Ingwannu commented on Aug 21, 2026

    @Ingwannu
    Owner

    Confirmed against current dev@401c24f747ad011bf340ee0ae6522b353c5dfb71.

    This is a real capability-boundary bug. The Responses parallel_tool_calls: true field is permissive: it allows the model to emit parallel calls, but it does not require every routed transport to carry a matching wire flag. Kiro already translates the tool catalog onto its serialized CodeWhisperer wire and emits no parallel-control field, so rejecting the request before dispatch is stricter than the client contract and now breaks ordinary Codex 0.149.0 tool turns.

    I will keep the fix narrow:

    • remove only the Kiro rejection for options.parallelToolCalls === true;
    • keep Kiro's routed catalog capability as supports_parallel_tool_calls: false and continue omitting any parallel field from the Kiro wire;
    • preserve all other Kiro capability guards, tool conversion, completion-tool serialization, and continuation behavior;
    • add a regression that parses the real Codex-shaped request, proves the permissive bit survives parsing, builds the Kiro request successfully, and verifies the translated tool catalog is present with no parallel-control field on the wire;
    • record the adapter-contract reason in the maintained transport architecture notes.

    I will open this as a Draft PR against dev. It will not be self-approved or self-merged; exact-head CI and independent maintainer review remain required.

  3. Ingwannu commented on Aug 21, 2026

    @Ingwannu
    Owner

    Implemented in Draft PR #2309 at exact head db040e70fe52a223c8d6e63bbc87a508f2ee7ae0. The fix removes only the overly strict Kiro rejection, preserves the parsed permission bit internally, keeps the Kiro catalog/wire serialized, and proves no parallel-control field is sent upstream. Validation: 55 Kiro tests passed; the affected Kiro/GUI/provider/pacing rerun passed 127/127; typecheck, privacy scan, and the 393-page docs build passed. The issue remains open pending exact-head CI and independent maintainer review.

  4. Ingwannu commented on Aug 21, 2026

    @Ingwannu
    Owner

    Draft PR #2309 is now fully green at exact head db040e70fe52a223c8d6e63bbc87a508f2ee7ae0. The issue remains open pending independent maintainer approval; I did not self-approve or merge.

  5. lidge-jun commented on Aug 21, 2026

    @lidge-jun
    Owner

    리뷰 · 우선순위 72 / 80

    지금 dev HEAD 401c24f74. #2306 vision routed sidecar 방금 들어옴. 이 이슈는 그 위. Codex CLI/App 0.149.0. OpenCodex 2.29.0. POST /v1/responses에 parallel_tool_calls: true + function bash. Kiro 어댑터가 업스트림 가기 전에 로컬 400. 본문 에러 문자열 Kiro does not support parallel tool calls. 재현 curl이 그거임. 라벨 provider-compatibility/provider/tools. 구현 PR은 #2309. 스플릿 이슈 아님.

    현재 dev가 그 400을 만듦. src/adapters/kiro.ts:316-330 validateKiroCapabilities. tool_choice는 auto/none만. parallelToolCalls === true면 throw. serviceTier throw. structured output throw. 호출은 src/adapters/kiro.ts:428-439 buildKiroPayload 첫 줄. :1866-1868 buildRequest가 build(parsed)를 탐. 업스트림 디스패치 전. HTTP 400은 그 throw. 카탈로그는 이미 false임. src/codex/catalog/parsing.ts:506-545 normalizeRoutedCatalogEntry. supports_parallel_tool_calls = isCursorEntry || parallelToolCalls === true. Kiro는 커서 슬롯 아님. src/providers/registry.ts:1199-1215 kiro 엔트리는 parallelToolCalls 키 자체가 없음. 기본 false. 라우티드 행이 false를 광고함. Codex 0.149는 그 비트를 무시하고 힌트를 true로 보냄. 본문이 가리킨 Codex 커밋이 supports_parallel_tool_calls를 ModelInfo에서 뺌. 카탈로그를 true로 뒤집어서 고치는 길이 아님.

    와이어. kiro.ts에서 parallel 문자열은 그 throw 두 줄뿐임. 페이로드에 parallel_tool_calls/parallelToolCalls를 안 씀. CodeWhisperer 직렬. 힌트를 수락해도 업스트림 필드는 안 생김. tool_choice: required/serviceTier/text 가드는 유지해야 함. #1650은 OpenAI Chat에 parallelToolCalls=false를 강제하는 이슈. 이 이슈랑 합치지 말 것. 중복 아님.

    #2309가 제안 매핑 그대로임. throw 삭제. 카탈로그 false 유지. 와이어에 병렬 필드 안 넣음. tests/kiro-adapter.test.ts가 parseRequest로 리포터 curl을 넣고 툴 카탈로그는 남고 병렬 키는 없음을 잠금. 이 이슈를 #2309 머지 전에 닫지 말 것. needs-info 아님. 재현이 코드와 같음.

    types.ts/config.ts 안 만짐. 스플릿 안 씹힘. 리베이스하지 말고 닫으라는 케이스 아님. #2188 L1–L9 사이드카 + routed vision(#2306) 이미 dev. x_search 넣지 말 것. Grok OAuth Chat 기본(#2255)/GUI 옵트인 Responses(#2266)/#2283이랑 다른 레인임. 프리뷰 배포 아님. #2292/#2293 윈도우 피커랑 안 겹침. 카탈로그는 Ox Alpha x-preview-f-free + deepseek-v4-flash-vision-exp. v2.29.0 태그됨. v2.30.0-preview.20260821 있음. 비전공자 유지. Codex 0.149 Kiro 툴 턴이 전부 400이라 72.

    해결방안: #2309로 가라. 이 이슈는 그 PR 머지 후 close. 카탈로그 supports_parallel_tool_calls를 true로 올리지 말 것. validateKiroCapabilities에서 parallel throw만 지워라. tool_choice/serviceTier/text 가드는 유지. 라벨 건드리지 말 것. #1650이랑 머지하지 말 것. 스플릿이 kiro.ts를 옮기면 리베이스하지 말고 닫고 다시 짜라. 지금은 그 정도 아님.

    이 댓글은 grok-bot이 작성했습니다

  6. yancy1997 commented on Aug 23, 2026

    @yancy1997

    Independent confirmation from another macOS setup:

    • Codex CLI 0.149.0 + OpenCodex 2.31.0 + Kiro
    • The routed kiro/gpt-5.6-luna catalog row already advertised supports_parallel_tool_calls: false.
    • An ordinary codex exec request still failed with the 502 wrapping Kiro does not support parallel tool calls.
    • The same local Responses endpoint returned HTTP 200 with parallel_tool_calls: false and HTTP 400 with parallel_tool_calls: true.
    • After removing only the Kiro rejection in validateKiroCapabilities and restarting OpenCodex, the same Codex request returned OK; a single shell tool call also succeeded.

    No parallel-control field was added to or sent on the Kiro wire. This independently confirms the mapping implemented by #2309. I did not run the upstream Bun test suite for this local verification.

  7. Ingwannu commented on Aug 23, 2026

    @Ingwannu
    Owner

    Thanks for the independent macOS confirmation. It matches the exact boundary fixed by #2309: current dev@4f41a8e93 contains commit db040e70f, which removes only the local Kiro rejection of the permissive parallel_tool_calls: true hint while keeping the routed catalog capability false and emitting no parallel-control field on the Kiro wire. The focused regression, exact-head cross-platform CI, reporter verification, and this second live confirmation are all consistent, so I am closing the issue as completed on dev. Users on OpenCodex 2.31.0 will need a release containing #2309 (or a current dev build); the already-published 2.31.0 package does not gain the fix retroactively.

  8. mchlkim commented on Aug 24, 2026

    @mchlkim
    Contributor

    Confirmed this still affects the latest stable release, v2.31.0.

    Environment:

    • OpenCodex: 2.31.0
    • Client: current Codex app-server
    • Endpoint: POST /v1/responses
    • Provider: Kiro

    Minimal result:

    • parallel_tool_calls: true -> OpenCodex rejects the request with Kiro does not support parallel tool calls (surfaced by Codex as a 502 Provider unreachable error)
    • the same request with parallel_tool_calls: false -> 200
    • restarting the Codex app-server does not change the result

    I also verified the release boundary:

    So #2309 is the correct fix, but it has not reached the latest stable package yet. Could this be included in the next patch release (or called out as a dev-only fix until then)?

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

    providerProvider adapters, OpenAI-compat presets, upstream API quirksprovider-compatibilityProvider compatibility reportstoolstool_calls, MCP, web-search / sidecar tools

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions