From 0031bf7a11ed5ebe37b500a71d572a1b5e0f2062 Mon Sep 17 00:00:00 2001 From: justsisyphus Date: Wed, 21 Jan 2026 11:00:30 +0900 Subject: [PATCH] fix(session-recovery): reorder error detection to prevent false tool_result_missing match Anthropic's extended thinking error messages contain 'tool_use' and 'tool_result' in the documentation URL text, causing incorrect detection as tool_result_missing instead of thinking_block_order. Fix: Check thinking_block_order BEFORE tool_result_missing. --- src/hooks/session-recovery/index.test.ts | 20 ++++++++++++++++++++ src/hooks/session-recovery/index.ts | 11 +++++++---- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/hooks/session-recovery/index.test.ts b/src/hooks/session-recovery/index.test.ts index 15b9e17d..97edc18f 100644 --- a/src/hooks/session-recovery/index.test.ts +++ b/src/hooks/session-recovery/index.test.ts @@ -199,5 +199,25 @@ describe("detectErrorType", () => { // #then should return thinking_block_order expect(result).toBe("thinking_block_order") }) + + it("should detect thinking_block_order even when error message contains tool_use/tool_result in docs URL", () => { + // #given Anthropic's extended thinking error with tool_use/tool_result in the documentation text + const error = { + error: { + type: "invalid_request_error", + message: + "messages.1.content.0.type: Expected `thinking` or `redacted_thinking`, but found `text`. " + + "When `thinking` is enabled, a final `assistant` message must start with a thinking block " + + "(preceeding the lastmost set of `tool_use` and `tool_result` blocks). " + + "We recommend you include thinking blocks from previous turns.", + }, + } + + // #when detectErrorType is called + const result = detectErrorType(error) + + // #then should return thinking_block_order (NOT tool_result_missing) + expect(result).toBe("thinking_block_order") + }) }) }) diff --git a/src/hooks/session-recovery/index.ts b/src/hooks/session-recovery/index.ts index 68ddb3fd..79f31fc5 100644 --- a/src/hooks/session-recovery/index.ts +++ b/src/hooks/session-recovery/index.ts @@ -125,10 +125,9 @@ function extractMessageIndex(error: unknown): number | null { export function detectErrorType(error: unknown): RecoveryErrorType { const message = getErrorMessage(error) - if (message.includes("tool_use") && message.includes("tool_result")) { - return "tool_result_missing" - } - + // IMPORTANT: Check thinking_block_order BEFORE tool_result_missing + // because Anthropic's extended thinking error messages contain "tool_use" and "tool_result" + // in the documentation URL, which would incorrectly match tool_result_missing if ( message.includes("thinking") && (message.includes("first block") || @@ -145,6 +144,10 @@ export function detectErrorType(error: unknown): RecoveryErrorType { return "thinking_disabled_violation" } + if (message.includes("tool_use") && message.includes("tool_result")) { + return "tool_result_missing" + } + return null }