From 7a896fd2b983c915862f3782b46a5236019e2883 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Fri, 2 Jan 2026 20:28:37 +0900 Subject: [PATCH] fix(token-limit-recovery): exclude thinking block errors from token limit detection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Removed 'invalid_request_error' from TOKEN_LIMIT_KEYWORDS (too broad) - Added THINKING_BLOCK_ERROR_PATTERNS to explicitly detect thinking block structure errors - Added isThinkingBlockError() function to filter these out before token limit checks - Prevents 'thinking block order' errors from triggering compaction instead of session-recovery 🤖 Generated with assistance of OhMyOpenCode (https://github.com/code-yeongyu/oh-my-opencode) --- .../parser.ts | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/hooks/anthropic-context-window-limit-recovery/parser.ts b/src/hooks/anthropic-context-window-limit-recovery/parser.ts index 6d36789..dda87bb 100644 --- a/src/hooks/anthropic-context-window-limit-recovery/parser.ts +++ b/src/hooks/anthropic-context-window-limit-recovery/parser.ts @@ -26,9 +26,23 @@ const TOKEN_LIMIT_KEYWORDS = [ "context length", "too many tokens", "non-empty content", - "invalid_request_error", ] +// Patterns that indicate thinking block structure errors (NOT token limit errors) +// These should be handled by session-recovery hook, not compaction +const THINKING_BLOCK_ERROR_PATTERNS = [ + /thinking.*first block/i, + /first block.*thinking/i, + /must.*start.*thinking/i, + /thinking.*redacted_thinking/i, + /expected.*thinking.*found/i, + /thinking.*disabled.*cannot.*contain/i, +] + +function isThinkingBlockError(text: string): boolean { + return THINKING_BLOCK_ERROR_PATTERNS.some((pattern) => pattern.test(text)) +} + const MESSAGE_INDEX_PATTERN = /messages\.(\d+)/ function extractTokensFromMessage(message: string): { current: number; max: number } | null { @@ -52,6 +66,9 @@ function extractMessageIndex(text: string): number | undefined { } function isTokenLimitError(text: string): boolean { + if (isThinkingBlockError(text)) { + return false + } const lower = text.toLowerCase() return TOKEN_LIMIT_KEYWORDS.some((kw) => lower.includes(kw.toLowerCase())) }