Merge pull request #3470 from omer-koren/fix/thinking-block-modified-recovery

fix(session-recovery): add thinking_block_modified error detection and recovery
This commit is contained in:
YeonGyu-Kim
2026-05-15 18:55:42 +09:00
committed by GitHub
3 changed files with 40 additions and 0 deletions
@@ -36,6 +36,31 @@ describe("detectErrorType", () => {
expect(result).toBe("thinking_disabled_violation")
})
it("#given a Bedrock thinking block modified error #when detecting #then returns thinking_block_modified", () => {
//#given
const error = {
message:
"undefined: The model returned the following errors: messages.17.content.28: `thinking` or `redacted_thinking` blocks in the latest assistant message cannot be modified. These blocks must remain as they were in the original response.",
}
//#when
const result = detectErrorType(error)
//#then
expect(result).toBe("thinking_block_modified")
})
it("#given a simple thinking block modified error #when detecting #then returns thinking_block_modified", () => {
//#given
const error = { message: "thinking blocks cannot be modified" }
//#when
const result = detectErrorType(error)
//#then
expect(result).toBe("thinking_block_modified")
})
it("#given an unrecognized error #when detecting #then returns null", () => {
//#given
const error = { message: "some random error" }
@@ -2,6 +2,7 @@ export type RecoveryErrorType =
| "tool_result_missing"
| "thinking_block_order"
| "thinking_disabled_violation"
| "thinking_block_modified"
| "assistant_prefill_unsupported"
| "unavailable_tool"
| null
@@ -77,6 +78,11 @@ export function detectErrorType(error: unknown): RecoveryErrorType {
return "thinking_block_order"
}
// Thinking block signature corruption (Bedrock compaction)
if (message.includes("thinking") && message.includes("cannot be modified")) {
return "thinking_block_modified"
}
if (message.includes("thinking is disabled") && message.includes("cannot contain")) {
return "thinking_disabled_violation"
}
+9
View File
@@ -99,6 +99,7 @@ export function createSessionRecoveryHook(ctx: PluginInput, options?: SessionRec
unavailable_tool: "Tool Recovery",
thinking_block_order: "Thinking Block Recovery",
thinking_disabled_violation: "Thinking Strip Recovery",
thinking_block_modified: "Thinking Block Recovery",
"assistant_prefill_unsupported": "Prefill Unsupported",
}
const toastMessages: Record<RecoveryErrorType & string, string> = {
@@ -106,6 +107,7 @@ export function createSessionRecoveryHook(ctx: PluginInput, options?: SessionRec
unavailable_tool: "Recovering from unavailable tool call...",
thinking_block_order: "Fixing message structure...",
thinking_disabled_violation: "Stripping thinking blocks...",
thinking_block_modified: "Stripping corrupted thinking blocks...",
"assistant_prefill_unsupported": "Prefill not supported; continuing without recovery.",
}
@@ -142,6 +144,13 @@ export function createSessionRecoveryHook(ctx: PluginInput, options?: SessionRec
const resumeConfig = extractResumeConfig(lastUser, sessionID)
await resumeSession(ctx.client, resumeConfig)
}
} else if (errorType === "thinking_block_modified") {
success = await recoverThinkingDisabledViolation(ctx.client, sessionID, failedMsg)
if (success && experimental?.auto_resume) {
const lastUser = findLastUserMessage(msgs ?? [])
const resumeConfig = extractResumeConfig(lastUser, sessionID)
await resumeSession(ctx.client, resumeConfig)
}
} else if (errorType === "assistant_prefill_unsupported") {
success = false
}