From 9aab980dc70bff01df3540c9508c97adea3c98d8 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Mon, 15 Dec 2025 19:02:31 +0900 Subject: [PATCH] fix(session-recovery): fallback to filesystem when API parts empty MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When OpenCode API doesn't return parts in message response, read directly from filesystem using readParts(messageID). This fixes session recovery failures where tool_use IDs couldn't be extracted because API response had empty parts array. 🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode) --- src/hooks/session-recovery/index.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/hooks/session-recovery/index.ts b/src/hooks/session-recovery/index.ts index 575b20a..fb37f8a 100644 --- a/src/hooks/session-recovery/index.ts +++ b/src/hooks/session-recovery/index.ts @@ -9,6 +9,7 @@ import { findMessagesWithThinkingOnly, injectTextPart, prependThinkingPart, + readParts, stripThinkingParts, } from "./storage" import type { MessageData } from "./types" @@ -100,7 +101,17 @@ async function recoverToolResultMissing( sessionID: string, failedAssistantMsg: MessageData ): Promise { - const parts = failedAssistantMsg.parts || [] + // Try API parts first, fallback to filesystem if empty + let parts = failedAssistantMsg.parts || [] + if (parts.length === 0 && failedAssistantMsg.info?.id) { + const storedParts = readParts(failedAssistantMsg.info.id) + parts = storedParts.map((p) => ({ + type: p.type === "tool" ? "tool_use" : p.type, + id: "callID" in p ? (p as { callID?: string }).callID : p.id, + name: "tool" in p ? (p as { tool?: string }).tool : undefined, + input: "state" in p ? (p as { state?: { input?: Record } }).state?.input : undefined, + })) + } const toolUseIds = extractToolUseIds(parts) if (toolUseIds.length === 0) {