From b45ede0b71d82f45c6bdab2d8d924fd476fcbb28 Mon Sep 17 00:00:00 2001 From: taetaetae Date: Sun, 1 Feb 2026 15:47:18 +0900 Subject: [PATCH] fix(kiro): handle empty content in messages to prevent Bad Request errors Problem: - OpenCode's /compaction command and auto-compaction (at 80%+ context) sends requests that can result in empty assistant message content - Kiro API strictly requires non-empty content for all messages - This causes 'Bad Request: Improperly formed request' errors - After compaction failure, the malformed message stays in history, breaking all subsequent requests in the session Solution: - Add fallback content for empty assistant messages in buildAssistantMessageFromOpenAI() - Add history truncation (max 50 messages) to prevent oversized requests - This ensures all messages have valid content before sending to Kiro API Fixes issues with: - /compaction command returning Bad Request - Auto-compaction breaking sessions - Conversations becoming unresponsive after compaction failure --- .../kiro/openai/kiro_openai_request.go | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/internal/translator/kiro/openai/kiro_openai_request.go b/internal/translator/kiro/openai/kiro_openai_request.go index 93914c6d..a621eebc 100644 --- a/internal/translator/kiro/openai/kiro_openai_request.go +++ b/internal/translator/kiro/openai/kiro_openai_request.go @@ -576,9 +576,23 @@ func processOpenAIMessages(messages gjson.Result, modelID, origin string) ([]Kir } } + // Truncate history if too long to prevent Kiro API errors + history = truncateHistoryIfNeeded(history) + return history, currentUserMsg, currentToolResults } +const kiroMaxHistoryMessages = 50 + +func truncateHistoryIfNeeded(history []KiroHistoryMessage) []KiroHistoryMessage { + if len(history) <= kiroMaxHistoryMessages { + return history + } + + log.Debugf("kiro-openai: truncating history from %d to %d messages", len(history), kiroMaxHistoryMessages) + return history[len(history)-kiroMaxHistoryMessages:] +} + // buildUserMessageFromOpenAI builds a user message from OpenAI format and extracts tool results func buildUserMessageFromOpenAI(msg gjson.Result, modelID, origin string) (KiroUserInputMessage, []KiroToolResult) { content := msg.Get("content") @@ -677,8 +691,20 @@ func buildAssistantMessageFromOpenAI(msg gjson.Result) KiroAssistantResponseMess } } + // CRITICAL FIX: Kiro API requires non-empty content for assistant messages + // This can happen with compaction requests or error recovery scenarios + finalContent := contentBuilder.String() + if strings.TrimSpace(finalContent) == "" { + if len(toolUses) > 0 { + finalContent = "I'll help you with that." + } else { + finalContent = "I understand." + } + log.Debugf("kiro-openai: assistant content was empty, using default: %s", finalContent) + } + return KiroAssistantResponseMessage{ - Content: contentBuilder.String(), + Content: finalContent, ToolUses: toolUses, } }