Submission checklist
Package (Required)
Related Issues / PRs
Reproduction Steps / Example Code (Python)
from typing import Any
from langchain.agents.middleware.summarization import SummarizationMiddleware
from langchain_core.language_models.chat_models import BaseChatModel
from langchain_core.messages import AIMessage, HumanMessage, RemoveMessage
from langchain_core.outputs import ChatResult
class RateLimitedModel(BaseChatModel):
"""Simulates a provider that is temporarily down (e.g. 429). Never touches the network."""
@property
def _llm_type(self) -> str:
return "failing-fake"
def _generate(self, messages: Any, stop: Any = None, run_manager: Any = None, **kwargs: Any) -> ChatResult:
raise RuntimeError("429 Too Many Requests (simulated transient failure)")
middleware = SummarizationMiddleware(
model=RateLimitedModel(),
trigger=("messages", 5),
keep=("messages", 2),
token_counter=len,
)
messages = []
for i in range(5):
messages.append(HumanMessage(content=f"user turn {i}", id=f"h{i}"))
messages.append(AIMessage(content=f"assistant turn {i}", id=f"a{i}"))
update = middleware.before_model({"messages": messages}, None)
print(isinstance(update["messages"][0], RemoveMessage)) # True: removes ALL messages
print(update["messages"][1].content)
# 'Here is a summary of the conversation to date:\n\nError generating summary: 429 Too Many Requests ...'
Error Message and Stack Trace (if applicable)
No exception is raised, that is the problem. Observed output of the repro:
state update returned by before_model:
RemoveMessage: ''
HumanMessage: 'Here is a summary of the conversation to date:\n\nError generating summary: 429 Too Many Req'
HumanMessage: 'user turn 4'
AIMessage: 'assistant turn 4'
8 of the 10 original messages are deleted and the inserted "summary" is the provider error string.
Description
When the summarization model call fails for any reason (rate limit, timeout, auth error), SummarizationMiddleware still reports success and rewrites the thread.
_create_summary and _acreate_summary catch every exception from the model call and return the string "Error generating summary: <exception>" as if it were a real summary (libs/langchain_v1/langchain/agents/middleware/summarization.py, around lines 815-822 and 841-848 on current master). before_model then proceeds normally: it emits RemoveMessage(REMOVE_ALL_MESSAGES) plus the new "summary", so the summarized messages are permanently deleted from the thread and the model is fed a summary that is literally the provider error text.
What I expect: a transient summary failure should not destroy state. Either the middleware skips summarization for that turn (keep the original messages, it can retry on a later turn) or the exception propagates so the caller can handle it.
What happens instead: see the repro. 8 of 10 messages are permanently dropped and the model continues with "Error generating summary: 429 Too Many Requests ..." as its memory of the conversation. A single 429 at the wrong moment silently corrupts a long running agent thread, and with a checkpointer the corrupted state is what gets persisted.
A contained fix would be to treat summary failure as "skip summarization this turn" (return no state update) rather than swapping real history for the error string. I have the fix and updated tests ready. I'd like to work on this, could you assign it to me?
System Info
System Information
OS: Windows
OS Version: 10.0.26200
Python Version: 3.11.0 (main, Oct 24 2022, 18:26:48) [MSC v.1933 64 bit (AMD64)]
Package Information
langchain_core: 1.4.9
langchain: 1.3.13
langsmith: 0.10.5
langchain_openai: 1.3.5
langgraph_sdk: 0.4.2
Also reproduced against current master (commit 7bf8fe2), where the same except blocks are present in summarization.py.
Submission checklist
Package (Required)
Related Issues / PRs
Reproduction Steps / Example Code (Python)
Error Message and Stack Trace (if applicable)
Description
When the summarization model call fails for any reason (rate limit, timeout, auth error), SummarizationMiddleware still reports success and rewrites the thread.
_create_summaryand_acreate_summarycatch every exception from the model call and return the string"Error generating summary: <exception>"as if it were a real summary (libs/langchain_v1/langchain/agents/middleware/summarization.py, around lines 815-822 and 841-848 on current master).before_modelthen proceeds normally: it emitsRemoveMessage(REMOVE_ALL_MESSAGES)plus the new "summary", so the summarized messages are permanently deleted from the thread and the model is fed a summary that is literally the provider error text.What I expect: a transient summary failure should not destroy state. Either the middleware skips summarization for that turn (keep the original messages, it can retry on a later turn) or the exception propagates so the caller can handle it.
What happens instead: see the repro. 8 of 10 messages are permanently dropped and the model continues with "Error generating summary: 429 Too Many Requests ..." as its memory of the conversation. A single 429 at the wrong moment silently corrupts a long running agent thread, and with a checkpointer the corrupted state is what gets persisted.
A contained fix would be to treat summary failure as "skip summarization this turn" (return no state update) rather than swapping real history for the error string. I have the fix and updated tests ready. I'd like to work on this, could you assign it to me?
System Info
System Information
Package Information
Also reproduced against current master (commit 7bf8fe2), where the same except blocks are present in summarization.py.