Skip to content

[BUG] SummarizingConversationManager truncation fallback gives up when the overflow is made of many text blocks ≤ 6K chars #5791

Description

@strandly-the-agent

Requested by: @ekumar96 — follow-up on #5603 / #5691 (Slack, 2026-11-03).

Human Overview

Checks

  • I have updated to the lastest minor and patch version of Strands
  • I have checked the documentation and this is not expected behavior
  • I have searched ./issues and there are no duplicates of my issue

SDK Language

Python

Strands Version

1.63.0

Language Runtime Version

Python 3.12

Operating System

macOS / Linux

Installation Method

pip

Steps to Reproduce

  1. Agent(conversation_manager=SummarizingConversationManager(), ...) with a file or Memory session manager.
  2. Send one user message whose content is many mid-sized text blocks, e.g. [{"text": "…5,000 chars…"}] * 80, large enough in total to overflow the model's context window.
  3. Send any further turn.

Reproduced 14/14 on Haiku 4.5, Sonnet 4.6 and Opus 5 (reporter), and deterministically at unit level: _truncate_largest_text_blocks([message]) returns 0 for such a message.

Expected Behavior

The truncation fallback added in #5603 / #5691 shrinks the oversized message until the context fits and the session keeps working.

Actual Behavior

_truncate_largest_text_blocks (strands-py/src/strands/agent/conversation_manager/compression/truncate_text.py) only truncates a block when len(text) > 3 * preserve_chars (6,000 chars). None of the 5,000-char blocks qualify, it returns 0, reduce_context re-raises ContextWindowOverflowException("Cannot summarize: insufficient messages for summarization"), and every later turn fails the same way — the session never recovers.

Possible Solution

Keep the largest-first / budget-doubling design from #5691 but make the preview size proportional for mid-sized blocks: keep min(preserve_chars, len // 4) at each end, so every truncation drops at least half of the block, and only skip blocks of preserve_chars (2K) or fewer. A message of 80 × 5K blocks then converges in 7 rounds (1 + 2 + … + 64) instead of failing forever. Alternative considered: collapsing the oversized message as a whole into one head+tail preview (a single round), rejected for now because it has to remove content blocks — including inside toolResult.content — and interleaved non-text blocks make that structurally riskier.

Additional Context

Same marker format as before; pinned messages are still skipped. Truncation still isn't persisted by repository session managers (noted in #5690), so with those the rounds repeat on every turn.

Related Issues

#5598, #5603, #5690, #5691

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-contextSession or context relatedbugSomething isn't workingpythonPull requests that update python code

    Type

    Fields

    Language

    Python

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions