Skip to content

feat(session): proactive TTL-based expiration of signed thinking blocks #91149

Description

@NOVA-Openclaw

Summary

Anthropic's signed thinking blocks have cryptographic signatures with a time-to-live (TTL). When these blocks are stored in session history and replayed on subsequent turns, the signatures can silently expire, causing 400 Invalid signature in thinking block errors that poison the session.

Issue #89684 shipped reactive auto-recovery for this error class. This issue requests the complementary proactive approach: track the signature TTL and strip expired thinking blocks from the session before they are included in the outbound request, preventing the error entirely.

Observed behavior

  • Session file accumulates signed thinking blocks over time (14 blocks across 55 messages in our case)
  • After some period (likely hours), the cryptographic signatures expire
  • Every subsequent Anthropic request replays the expired signatures and gets an instant HTTP 400
  • The session is bricked for that provider until manually cleared or auto-recovery kicks in
  • Auto-recovery (feat(session): auto-recovery for 'Invalid signature in thinking block' errors #89684) helps but is reactive — the first request still fails, and the error+recovery path adds latency and log noise

Proposed behavior

OpenClaw should track the TTL of signed thinking blocks (either by querying Anthropic's documented TTL or by recording the block creation timestamp) and proactively strip or redact blocks whose signatures have expired before including them in the outbound message payload.

This could be implemented as:

  1. A timestamp annotation on thinking blocks when they are first persisted to the session file
  2. A configurable TTL (e.g. session.thinkingBlockTtl) that defaults to a safe value
  3. A pre-request sanitization pass that drops thinking blocks older than the TTL
  4. Alternatively, during session hydration / context assembly, filter out blocks past TTL

Why proactive > reactive

  • No wasted API calls — reactive recovery still sends the bad request first
  • No error log noise — the 400 never fires
  • Cleaner context windows — expired thinking blocks consume tokens but provide no value (the model can't see redacted thinking anyway)
  • Compaction-friendly — naturally shrinks session context over time

Environment

  • OpenClaw 2026.5.26 (1d64a32)
  • Model: anthropic/claude-opus-4-6 with thinking: adaptive
  • contextPruning.mode: cache-ttl, ttl: 1h
  • Session: 55 messages, 14 thinking blocks, 202K estimated tokens
  • Error: messages.5.content.10: Invalid signature in thinking block

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.impact:auth-providerAuth, provider routing, model choice, or SecretRef resolution may break.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions