From c662f9c240d99f73d4b76c565229b2b9cd49f431 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Fri, 12 Dec 2025 19:27:37 +0900 Subject: [PATCH] fix(session-recovery): handle empty content in user messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously only checked assistant messages for empty content. Now checks all messages except the final assistant message, following Anthropic API rules. Fixes: "messages.N: all messages must have non-empty content" error 🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode) --- src/hooks/session-recovery/storage.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/hooks/session-recovery/storage.ts b/src/hooks/session-recovery/storage.ts index 2598129..2719929 100644 --- a/src/hooks/session-recovery/storage.ts +++ b/src/hooks/session-recovery/storage.ts @@ -122,8 +122,12 @@ export function findEmptyMessages(sessionID: string): string[] { const messages = readMessages(sessionID) const emptyIds: string[] = [] - for (const msg of messages) { - if (msg.role !== "assistant") continue + for (let i = 0; i < messages.length; i++) { + const msg = messages[i] + + // API rule: only the final assistant message may have empty content + const isLastMessage = i === messages.length - 1 + if (isLastMessage && msg.role === "assistant") continue if (!messageHasContent(msg.id)) { emptyIds.push(msg.id) @@ -139,7 +143,12 @@ export function findEmptyMessageByIndex(sessionID: string, targetIndex: number): if (targetIndex < 0 || targetIndex >= messages.length) return null const targetMsg = messages[targetIndex] - if (targetMsg.role !== "assistant") return null + + // API rule: only the final assistant message may have empty content + // All other messages (user AND assistant) must have non-empty content + const isLastMessage = targetIndex === messages.length - 1 + if (isLastMessage && targetMsg.role === "assistant") return null + if (messageHasContent(targetMsg.id)) return null return targetMsg.id