Skip to content

fix(kiro): resolve Improperly formed request when tool_calls in history (#1184)#1209

Open
DuongStark wants to merge 1 commit into
decolua:masterfrom
DuongStark:fix/issue-1184-kiro-improperly-formed-request
Open

fix(kiro): resolve Improperly formed request when tool_calls in history (#1184)#1209
DuongStark wants to merge 1 commit into
decolua:masterfrom
DuongStark:fix/issue-1184-kiro-improperly-formed-request

Conversation

@DuongStark
Copy link
Copy Markdown

Problem

Kiro returns 400 Improperly formed request when conversations have many tool calls (reported in #1184). Root cause: openai-to-kiro.js drops messages and tool schemas under certain conditions.

Root Causes Fixed

Bug 1 — tools schema lost when conversation starts with assistant turns
convertMessages() used history.length === 0 to decide when to attach the tools schema. When the first messages are assistant turns, the first user flush sees a non-empty history and the schema is never attached.

Fix: use a toolsAttached flag instead.

Bug 2 — missing tool schema when body.tools is empty (main cause of #1184)
Kiro rejects requests that reference toolUses/toolResults in history without a matching tools schema in userInputMessageContext. When clients omit body.tools but the history still contains assistant.tool_calls, 9router sent no schema → Kiro returned 400.

Fix: in buildKiroPayload(), scan message history for tool_calls and synthesize a minimal tool schema when body.tools is empty.

Bug 3 — toolResults lost when merging consecutive user messages
The merge loop concatenated content strings but silently dropped userInputMessageContext (which carries toolResults) from the second message.

Fix: merge userInputMessageContext by concatenating array fields.

Bonus — currentMessage extraction reordered history
The old splice-from-end scan could pull a non-final user turn out of the middle of history, breaking chronological order.

Fix: use history.pop() when the last entry is a user turn; otherwise synthesize a Continue message.

Tests

All 7 existing unit tests pass:

npx vitest run tests/unit/openai-to-kiro.test.js
✓ tests/unit/openai-to-kiro.test.js (7 tests)

Closes #1184

…ry (decolua#1184)

- Use toolsAttached flag instead of history.length === 0 to attach tools
  schema, fixing loss of schema when conversation starts with assistant turns
- Synthesize minimal tool schema from tool_calls in history when body.tools
  is empty — prevents Kiro 400 when clients omit tools but history has tool_calls
- Merge userInputMessageContext (toolResults) when collapsing consecutive
  user messages so tool results are not silently dropped
- Replace splice-from-end currentMessage extraction with history.pop() to
  preserve chronological order; synthesize Continue turn when last message
  is not a user turn

All 7 unit tests pass (npx vitest run tests/unit/openai-to-kiro.test.js)
@DungAT98
Copy link
Copy Markdown

@decolua Could you please check it. It blocked us to use claude code :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Anyone knows this error? Kiro reject request with 400 - message: Improperly formed request.

3 participants