Summary
When using Claude models with extended thinking via Bedrock, conversations eventually hit Invalid signature in thinking block errors, making the session unusable until a manual /reset. This is a recurring issue affecting long-lived sessions.
Environment
- OpenClaw version: 2026.2.23 through 2026.3.11 (confirmed across multiple versions)
- Provider:
amazon-bedrock (bedrock-converse-stream API)
- Model:
global.anthropic.claude-opus-4-6-v1
- Thinking mode: enabled (extended thinking / reasoning)
Error Message
The model returned the following errors: messages.N.content.M: Invalid signature in thinking block
Where N is a message index in the conversation history and M is the content block index.
Root Cause Analysis
Causal Chain
-
Bedrock returns empty thinkingSignature: In some runs, the bedrock-converse-stream API returns a thinking block with thinkingSignature: "" (empty string). Other thinking blocks in the same session have signatures of 356-2344 characters.
-
Empty signature is persisted: OpenClaw stores the thinking block with the empty signature into the session JSONL transcript without validation.
-
Later API call fails validation: When the session history is replayed on a subsequent turn (hours or turns later), the Anthropic API server-side validates the signature of every thinking block. The empty/corrupted signature fails → Invalid signature in thinking block → stopReason: "error", empty assistant content.
-
User sees no response: The error is logged but not surfaced as a visible error message to the user. The agent appears to silently stop responding.
Evidence from Session Logs
Incident 1 (2026-03-04)
- Session
318ff11f, model global.anthropic.claude-opus-4-6-v1
- Error at
2026-03-04T04:59:17Z: Signature expired (AWS SigV4 clock skew, separate issue)
- Also observed thinking block signature validation failures leading to session reset
Incident 2 (2026-03-09, fully traced)
- Session
7cc28e8f-topic-182
- Run at
04:06 UTC: thinking block at message index 442 had thinkingSignature: "", while 15 previous thinking blocks in the same session had valid signatures (356-2344 chars)
- 7 hours later at
11:27 UTC: API returned messages.53.content.0: Invalid signature in thinking block
- Result:
stopReason: "error", assistant content empty, user saw no response
- Additional errors: 3×
http2 request did not get a response, 1× prompt is too long: 243116 tokens > 200000 maximum
- Fixed only by
/reset
Incident 3 (2026-03-10)
- Session
b43cca68, same pattern, reset at 07:50 UTC
Incident 4 (2026-03-12)
- Session
7cc28e8f-topic-182 (new session after reset), recurred, reset at 23:03 UTC
Incident 5 (2026-03-13)
- Session
8ff333de-topic-2183: errors including http2 request did not get a response and system encountered an unexpected error, reset at 08:27 UTC
- Same user also reported
messages.33.content.28: Invalid signature in thinking block from a different session
Affected Setup
Two agents (main and neal_5) on the same gateway, both affected.
Code Analysis
OpenClaw already has related logic:
-
truncateHistoryText (reply & compact modules): Deletes thinkingSignature when truncating thinking text:
if ("thinkingSignature" in entry) {
delete entry.thinkingSignature;
truncated = true;
}
-
parseThinkingSignature (API conversion): Returns null for empty strings (good), but the thinking block may still be included without a valid signature depending on the code path:
function parseThinkingSignature(value) {
if (typeof value !== "string" || value.trim().length === 0) return null;
// ...
}
-
No validation on ingest: When the streaming API response is received, there is no check that thinkingSignature is non-empty before persisting to the session JSONL.
Proposed Fixes
Short-term
-
Validate signature on persist: Before writing a thinking block to session JSONL, validate thinkingSignature is non-empty. If empty, strip the signature (or the entire thinking block).
-
Auto-recover on replay error: When the API returns Invalid signature in thinking block, strip the offending thinking block(s) and retry, instead of returning stopReason: "error" with empty content.
-
Surface errors to users: stopReason: "error" with errorMessage should produce a visible error, not silent empty response.
Long-term
-
Compaction should strip old thinking blocks: During conversation compaction, thinking blocks from older turns should be stripped (keep only text), since signatures may expire.
-
Auto-reset on repeated signature errors: After N consecutive signature errors, auto-compact or auto-reset.
Reproduction
Intermittent, tied to Bedrock streaming API occasionally returning empty thinkingSignature:
- Use Claude model with extended thinking via Bedrock
- Long conversations (50+ turns)
- Wait hours between turns
Impact
- Frequency: Multiple times per week
- UX: Agent silently stops responding; requires
/reset losing all context
- Workaround:
/reset the session
Summary
When using Claude models with extended thinking via Bedrock, conversations eventually hit
Invalid signature in thinking blockerrors, making the session unusable until a manual/reset. This is a recurring issue affecting long-lived sessions.Environment
amazon-bedrock(bedrock-converse-streamAPI)global.anthropic.claude-opus-4-6-v1Error Message
Where
Nis a message index in the conversation history andMis the content block index.Root Cause Analysis
Causal Chain
Bedrock returns empty
thinkingSignature: In some runs, thebedrock-converse-streamAPI returns a thinking block withthinkingSignature: ""(empty string). Other thinking blocks in the same session have signatures of 356-2344 characters.Empty signature is persisted: OpenClaw stores the thinking block with the empty signature into the session JSONL transcript without validation.
Later API call fails validation: When the session history is replayed on a subsequent turn (hours or turns later), the Anthropic API server-side validates the signature of every thinking block. The empty/corrupted signature fails →
Invalid signature in thinking block→stopReason: "error", empty assistant content.User sees no response: The error is logged but not surfaced as a visible error message to the user. The agent appears to silently stop responding.
Evidence from Session Logs
Incident 1 (2026-03-04)
318ff11f, modelglobal.anthropic.claude-opus-4-6-v12026-03-04T04:59:17Z:Signature expired(AWS SigV4 clock skew, separate issue)Incident 2 (2026-03-09, fully traced)
7cc28e8f-topic-18204:06 UTC: thinking block at message index 442 hadthinkingSignature: "", while 15 previous thinking blocks in the same session had valid signatures (356-2344 chars)11:27 UTC: API returnedmessages.53.content.0: Invalid signature in thinking blockstopReason: "error", assistant content empty, user saw no responsehttp2 request did not get a response, 1×prompt is too long: 243116 tokens > 200000 maximum/resetIncident 3 (2026-03-10)
b43cca68, same pattern, reset at07:50 UTCIncident 4 (2026-03-12)
7cc28e8f-topic-182(new session after reset), recurred, reset at23:03 UTCIncident 5 (2026-03-13)
8ff333de-topic-2183: errors includinghttp2 request did not get a responseandsystem encountered an unexpected error, reset at08:27 UTCmessages.33.content.28: Invalid signature in thinking blockfrom a different sessionAffected Setup
Two agents (
mainandneal_5) on the same gateway, both affected.Code Analysis
OpenClaw already has related logic:
truncateHistoryText(reply & compact modules): DeletesthinkingSignaturewhen truncating thinking text:parseThinkingSignature(API conversion): Returnsnullfor empty strings (good), but the thinking block may still be included without a valid signature depending on the code path:No validation on ingest: When the streaming API response is received, there is no check that
thinkingSignatureis non-empty before persisting to the session JSONL.Proposed Fixes
Short-term
Validate signature on persist: Before writing a thinking block to session JSONL, validate
thinkingSignatureis non-empty. If empty, strip the signature (or the entire thinking block).Auto-recover on replay error: When the API returns
Invalid signature in thinking block, strip the offending thinking block(s) and retry, instead of returningstopReason: "error"with empty content.Surface errors to users:
stopReason: "error"witherrorMessageshould produce a visible error, not silent empty response.Long-term
Compaction should strip old thinking blocks: During conversation compaction, thinking blocks from older turns should be stripped (keep only text), since signatures may expire.
Auto-reset on repeated signature errors: After N consecutive signature errors, auto-compact or auto-reset.
Reproduction
Intermittent, tied to Bedrock streaming API occasionally returning empty
thinkingSignature:Impact
/resetlosing all context/resetthe session