langchain - ✅(Solved) Fix Using compaction causes Anthropic's API to fail when agent invoked with print_mode="messages" or when streaming with stream_mode="messages" [1 pull requests, 2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
langchain-ai/langchain#36976Fetched 2026-04-24 05:51:26
View on GitHub
Comments
2
Participants
2
Timeline
7
Reactions
0
Timeline (top)
labeled ×3commented ×2cross-referenced ×1issue_type_added ×1

I am trying to use streaming with "messages" mode for my agent with custom tools and compaction for context management.

It appears that the index field produced by the LangChain during "messages" mode streaming is not stripped off and result in the error in the subsequent Anthropic API request. I have seen it multiple times when my agent first performed compaction and then used any of my custom tool which resulted in a new request to Anthropic API and a corresponding "Extra inputs are not permitted" error. I managed to reproduced it in minimal, reliable example by using print_mode="messages" in agent.invoke() and handcrafted messages.

I don't know LangChain internals too well, but in my experiments it looked like the "index" field is required for "messages" streaming mode. I think the best solution would be to add a dedicated block for formatting compaction blocks in _format_messages function of langchain_anthropic/chat_models.py that formats LangChain messages before sending them to the Anthropic API:

                    elif block["type"] == "compaction":
                        content.append(
                            {
                                k: v
                                for k, v in block.items()
                                if k in ("type", "content", "cache_control")
                            },
                        )

I think this is clean and shouldn't break anything as it only strips extra fields from compaction blocks sent to the Anthropic API

Error Message


BadRequestError Traceback (most recent call last) Cell In[20], line 3 1 from langchain_core.messages import HumanMessage 2 ----> 3 result2 = agent.invoke({"messages": result["messages"] + [HumanMessage(content="What is my name?")]}, print_mode=("messages"))

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langgraph/pregel/main.py:3365, in Pregel.invoke(self, input, config, context, stream_mode, print_mode, output_keys, interrupt_before, interrupt_after, durability, version, **kwargs) 3362 chunks.append(chunk) 3363 else: 3364 # v1: collect interrupts from updates stream -> 3365 for chunk in self.stream( 3366 input, 3367 config, 3368 context=context, 3369 stream_mode=( 3370 ["updates", "values"] if stream_mode == "values" else stream_mode 3371 ), 3372 print_mode=print_mode, 3373 output_keys=output_keys, 3374 interrupt_before=interrupt_before, 3375 interrupt_after=interrupt_after, 3376 durability=durability, 3377 **kwargs, 3378 ): 3379 if stream_mode == "values": 3380 if len(chunk) == 2:

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langgraph/pregel/main.py:2759, in Pregel.stream(self, input, config, context, stream_mode, print_mode, output_keys, interrupt_before, interrupt_after, durability, subgraphs, debug, version, **kwargs) 2757 for task in loop.match_cached_writes(): 2758 loop.output_writes(task.id, task.writes, cached=True) -> 2759 for _ in runner.tick( 2760 [t for t in loop.tasks.values() if not t.writes], 2761 timeout=self.step_timeout, 2762 get_waiter=get_waiter, 2763 schedule_task=loop.accept_push, 2764 ): 2765 # emit output 2766 yield from _output( 2767 stream_mode, 2768 print_mode, (...) 2774 _state_mapper, 2775 ) 2776 loop.after_tick()

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langgraph/pregel/_runner.py:167, in PregelRunner.tick(self, tasks, reraise, timeout, retry_policy, get_waiter, schedule_task) 165 t = tasks[0] 166 try: --> 167 run_with_retry( 168 t, 169 retry_policy, 170 configurable={ 171 CONFIG_KEY_CALL: partial( 172 _call, 173 weakref.ref(t), 174 retry_policy=retry_policy, 175 futures=weakref.ref(futures), 176 schedule_task=schedule_task, 177 submit=self.submit, 178 ), 179 }, 180 ) 181 self.commit(t, None) 182 except Exception as exc:

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langgraph/pregel/_retry.py:126, in run_with_retry(task, retry_policy, configurable) 124 task.writes.clear() 125 # run the task --> 126 return task.proc.invoke(task.input, config) 127 except ParentCommand as exc: 128 ns: str = config[CONF][CONFIG_KEY_CHECKPOINT_NS]

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langgraph/_internal/_runnable.py:656, in RunnableSeq.invoke(self, input, config, **kwargs) 654 # run in context 655 with set_config_context(config, run) as context: --> 656 input = context.run(step.invoke, input, config, **kwargs) 657 else: 658 input = step.invoke(input, config)

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langgraph/_internal/_runnable.py:400, in RunnableCallable.invoke(self, input, config, **kwargs) 398 run_manager.on_chain_end(ret) 399 else: --> 400 ret = self.func(*args, **kwargs) 401 if self.recurse and isinstance(ret, Runnable): 402 return ret.invoke(input, config)

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain/agents/factory.py:1310, in create_agent.<locals>.model_node(state, runtime) 1298 request = ModelRequest( 1299 model=model, 1300 tools=default_tools, (...) 1306 runtime=runtime, 1307 ) 1309 if wrap_model_call_handler is None: -> 1310 model_response = _execute_model_sync(request) 1311 return _build_commands(model_response) 1313 result = wrap_model_call_handler(request, _execute_model_sync)

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain/agents/factory.py:1282, in create_agent.<locals>.execute_model_sync(request) 1279 if request.system_message: 1280 messages = [request.system_message, *messages] -> 1282 output = model.invoke(messages) 1283 if name: 1284 output.name = name

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain_core/runnables/base.py:5695, in RunnableBindingBase.invoke(self, input, config, **kwargs) 5688 @override 5689 def invoke( 5690 self, (...) 5693 **kwargs: Any | None, 5694 ) -> Output: -> 5695 return self.bound.invoke( 5696 input, 5697 self._merge_configs(config), 5698 **{**self.kwargs, **kwargs}, 5699 )

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain_core/language_models/chat_models.py:455, in BaseChatModel.invoke(self, input, config, stop, **kwargs) 441 @override 442 def invoke( 443 self, (...) 448 **kwargs: Any, 449 ) -> AIMessage: 450 config = ensure_config(config) 451 return cast( 452 "AIMessage", 453 cast( 454 "ChatGeneration", --> 455 self.generate_prompt( 456 [self._convert_input(input)], 457 stop=stop, 458 callbacks=config.get("callbacks"), 459 tags=config.get("tags"), 460 metadata=config.get("metadata"), 461 run_name=config.get("run_name"), 462 run_id=config.pop("run_id", None), 463 **kwargs, 464 ).generations[0][0], 465 ).message, 466 )

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain_core/language_models/chat_models.py:1198, in BaseChatModel.generate_prompt(self, prompts, stop, callbacks, **kwargs) 1189 @override 1190 def generate_prompt( 1191 self, (...) 1195 **kwargs: Any, 1196 ) -> LLMResult: 1197 prompt_messages = [p.to_messages() for p in prompts] -> 1198 return self.generate(prompt_messages, stop=stop, callbacks=callbacks, **kwargs)

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain_core/language_models/chat_models.py:1005, in BaseChatModel.generate(self, messages, stop, callbacks, tags, metadata, run_name, run_id, **kwargs) 1002 for i, m in enumerate(input_messages): 1003 try: 1004 results.append( -> 1005 self._generate_with_cache( 1006 m, 1007 stop=stop, 1008 run_manager=run_managers[i] if run_managers else None, 1009 **kwargs, 1010 ) 1011 ) 1012 except BaseException as e: 1013 if run_managers:

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain_core/language_models/chat_models.py:1310, in BaseChatModel._generate_with_cache(self, messages, stop, run_manager, **kwargs) 1308 result = generate_from_stream(iter(chunks)) 1309 elif inspect.signature(self._generate).parameters.get("run_manager"): -> 1310 result = self._generate( 1311 messages, stop=stop, run_manager=run_manager, **kwargs 1312 ) 1313 else: 1314 result = self._generate(messages, stop=stop, **kwargs)

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain_anthropic/chat_models.py:1566, in ChatAnthropic._generate(self, messages, stop, run_manager, **kwargs) 1564 data = self._create(payload) 1565 except anthropic.BadRequestError as e: -> 1566 _handle_anthropic_bad_request(e) 1567 return self._format_output(data, **kwargs)

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain_anthropic/chat_models.py:1564, in ChatAnthropic._generate(self, messages, stop, run_manager, **kwargs) 1562 payload = self._get_request_payload(messages, stop=stop, **kwargs) 1563 try: -> 1564 data = self._create(payload) 1565 except anthropic.BadRequestError as e: 1566 _handle_anthropic_bad_request(e)

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain_anthropic/chat_models.py:1228, in ChatAnthropic._create(self, payload) 1226 def _create(self, payload: dict) -> Any: 1227 if "betas" in payload: -> 1228 return self._client.beta.messages.create(**payload) 1229 return self._client.messages.create(**payload)

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/anthropic/_utils/_utils.py:283, in required_args.<locals>.inner.<locals>.wrapper(*args, **kwargs) 281 msg = f"Missing required argument: {quote(missing[0])}" 282 raise TypeError(msg) --> 283 return func(*args, **kwargs)

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/anthropic/resources/beta/messages/messages.py:1100, in Messages.create(self, max_tokens, messages, model, cache_control, container, context_management, inference_geo, mcp_servers, metadata, output_config, output_format, service_tier, speed, stop_sequences, stream, system, temperature, thinking, tool_choice, tools, top_k, top_p, user_profile_id, betas, extra_headers, extra_query, extra_body, timeout) 1093 merged_output_config = _merge_output_configs(output_config, output_format) 1095 extra_headers = { 1096 **strip_not_given({"anthropic-beta": ",".join(str(e) for e in betas) if is_given(betas) else not_given}), 1097 **_stainless_helper_header(tools, messages), 1098 **(extra_headers or {}), 1099 } -> 1100 return self._post( 1101 "/v1/messages?beta=true", 1102 body=maybe_transform( 1103 { 1104 "max_tokens": max_tokens, 1105 "messages": messages, 1106 "model": model, 1107 "cache_control": cache_control, 1108 "container": container, 1109 "context_management": context_management, 1110 "inference_geo": inference_geo, 1111 "mcp_servers": mcp_servers, 1112 "metadata": metadata, 1113 "output_config": merged_output_config, 1114 "output_format": omit, 1115 "service_tier": service_tier, 1116 "speed": speed, 1117 "stop_sequences": stop_sequences, 1118 "stream": stream, 1119 "system": system, 1120 "temperature": temperature, 1121 "thinking": thinking, 1122 "tool_choice": tool_choice, 1123 "tools": tools, 1124 "top_k": top_k, 1125 "top_p": top_p, 1126 "user_profile_id": user_profile_id, 1127 }, 1128 message_create_params.MessageCreateParamsStreaming 1129 if stream 1130 else message_create_params.MessageCreateParamsNonStreaming, 1131 ), 1132 options=make_request_options( 1133 extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout 1134 ), 1135 cast_to=BetaMessage, 1136 stream=stream or False, 1137 stream_cls=Stream[BetaRawMessageStreamEvent], 1138 )

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/anthropic/_base_client.py:1368, in SyncAPIClient.post(self, path, cast_to, body, content, options, files, stream, stream_cls) 1359 warnings.warn( 1360 "Passing raw bytes as body is deprecated and will be removed in a future version. " 1361 "Please pass raw bytes via the content parameter instead.", 1362 DeprecationWarning, 1363 stacklevel=2, 1364 ) 1365 opts = FinalRequestOptions.construct( 1366 method="post", url=path, json_data=body, content=content, files=to_httpx_files(files), **options 1367 ) -> 1368 return cast(ResponseT, self.request(cast_to, opts, stream=stream, stream_cls=stream_cls))

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/anthropic/_base_client.py:1141, in SyncAPIClient.request(self, cast_to, options, stream, stream_cls) 1138 err.response.read() 1140 log.debug("Re-raising status error") -> 1141 raise self._make_status_error_from_response(err.response) from None 1143 break 1145 assert response is not None, "could not resolve response (should never happen)"

BadRequestError: Error code: 400 - {'type': 'error', 'error': {'type': 'invalid_request_error', 'message': 'messages.63.content.0.compaction.index: Extra inputs are not permitted'}, 'request_id': 'req_011CaMEooKTSiAAWiBiYo2yL'} During task with name 'model' and id '62a7431b-3f32-e2e5-fbdf-1040c1bf2015'

Root Cause

I am trying to use streaming with "messages" mode for my agent with custom tools and compaction for context management.

It appears that the index field produced by the LangChain during "messages" mode streaming is not stripped off and result in the error in the subsequent Anthropic API request. I have seen it multiple times when my agent first performed compaction and then used any of my custom tool which resulted in a new request to Anthropic API and a corresponding "Extra inputs are not permitted" error. I managed to reproduced it in minimal, reliable example by using print_mode="messages" in agent.invoke() and handcrafted messages.

I don't know LangChain internals too well, but in my experiments it looked like the "index" field is required for "messages" streaming mode. I think the best solution would be to add a dedicated block for formatting compaction blocks in _format_messages function of langchain_anthropic/chat_models.py that formats LangChain messages before sending them to the Anthropic API:

                    elif block["type"] == "compaction":
                        content.append(
                            {
                                k: v
                                for k, v in block.items()
                                if k in ("type", "content", "cache_control")
                            },
                        )

I think this is clean and shouldn't break anything as it only strips extra fields from compaction blocks sent to the Anthropic API

Fix Action

Fix / Workaround

  • This is a bug, not a usage question.
  • I added a clear and descriptive title that summarizes this issue.
  • I used the GitHub search to find a similar question and didn't find it.
  • I am sure that this is a bug in LangChain rather than my code.
  • The bug is not resolved by updating to the latest stable version of LangChain (or the specific integration package).
  • This is not related to the langchain-community package.
  • I posted a self-contained, minimal, reproducible example. A maintainer can copy it and run it AS IS.

Other Dependencies

anthropic: 0.96.0 httpx: 0.28.1 jsonpatch: 1.33 langgraph: 1.1.9 orjson: 3.11.8 packaging: 26.1 pydantic: 2.13.3 pyyaml: 6.0.3 requests: 2.33.1 requests-toolbelt: 1.0.0 tenacity: 9.1.4 typing-extensions: 4.15.0 uuid-utils: 0.14.1 xxhash: 3.6.0 zstandard: 0.25.0

PR fix notes

PR #36979: fix(anthropic): strip stream-only metadata from compaction blocks

Description (problem / solution / changelog)

Fixes #36976


Strip stream-only metadata from Anthropic compaction blocks before replaying them into follow-up requests. Added a unit regression test for streamed compaction blocks and verified the original live reproduction now succeeds on the second print_mode=messages invoke.

Verified locally with the focused Anthropic unit tests, the original live Anthropic reproduction, and uv ruff/mypy on the touched files.

This contribution was prepared with AI-agent assistance and manually validated.

Changed files

  • libs/partners/anthropic/langchain_anthropic/chat_models.py (modified, +8/-0)
  • libs/partners/anthropic/tests/unit_tests/test_chat_models.py (modified, +26/-0)

Code Example

import anthropic

from langchain.agents import create_agent
from langchain_anthropic import ChatAnthropic
from langchain_core.messages import HumanMessage

model = ChatAnthropic(
    model="claude-sonnet-4-6",
    betas=["compact-2026-01-12"],
    max_tokens=8000,
    context_management={
        "edits": [
            {
                "type": "compact_20260112",
                "trigger": {"type": "input_tokens", "value": 50000},
            }
        ]
    },
)

agent = create_agent(
    model=model,
)

client = anthropic.Anthropic()

SYSTEM_MESSAGE = "You are a helpful assistant that answers questions thoroughly and in great detail."

FILLER_PARAGRAPH = FILLER_PARAGRAPH = (
    "Brand24 is a social listening and media monitoring platform that helps businesses track "
    "online mentions of their brand, products, and competitors across social media, news sites, "
    "blogs, forums, podcasts, and more. The platform provides real-time alerts, sentiment analysis, "
    "influencer identification, and detailed analytics to help companies understand their online "
    "presence and make data-driven marketing decisions. With Brand24, users can monitor keywords, "
    "hashtags, and phrases across millions of online sources, gaining valuable insights into "
    "customer opinions, industry trends, and competitive landscape. The tool offers features like "
    "automated reports, discussion volume charts, mention analytics, and integration with popular "
    "business tools. Companies use Brand24 to protect their reputation, measure campaign "
    "effectiveness, find sales leads, and improve customer service by responding quickly to "
    "online conversations about their brand."
) * 5

N = 31

history = []
for i in range(N):
    history.append({"role": "user", "content": f"Question {i+1}: Tell me more about topic number {i+1}. {FILLER_PARAGRAPH}"})
    history.append({"role": "assistant", "content": f"Answer {i+1}: Here is a detailed response about topic {i+1}. {FILLER_PARAGRAPH}"})
history.append({"role": "user", "content": "Hi, my name is John"})

token_count = client.messages.count_tokens(
    model="claude-sonnet-4-6",
    system=SYSTEM_MESSAGE,
    messages=history,
)
assert token_count.input_tokens > 50_000, f"Expected >50k tokens, got {token_count.input_tokens:,}"
assert token_count.input_tokens < 60_000, f"Expected <60k tokens, got {token_count.input_tokens:,}"

# The first request triggers compaction. With print_mode="updates" everything is fine
result = agent.invoke({"messages": history}, print_mode="updates")
result2 = agent.invoke({"messages": result["messages"] + [HumanMessage(content="What is my name?")]}, print_mode="updates")

# Now we make the first request with print_mode="messages". The second request produce an error
result = agent.invoke({"messages": history}, print_mode="messages")  # Works fine
result2 = agent.invoke({"messages": result["messages"] + [HumanMessage(content="What is my name?")]}, print_mode=("messages"))  # Produces an error

---

---------------------------------------------------------------------------
BadRequestError                           Traceback (most recent call last)
Cell In[20], line 3
      1 from langchain_core.messages import HumanMessage
      2 
----> 3 result2 = agent.invoke({"messages": result["messages"] + [HumanMessage(content="What is my name?")]}, print_mode=("messages"))

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langgraph/pregel/main.py:3365, in Pregel.invoke(self, input, config, context, stream_mode, print_mode, output_keys, interrupt_before, interrupt_after, durability, version, **kwargs)
   3362             chunks.append(chunk)
   3363 else:
   3364     # v1: collect interrupts from updates stream
-> 3365     for chunk in self.stream(
   3366         input,
   3367         config,
   3368         context=context,
   3369         stream_mode=(
   3370             ["updates", "values"] if stream_mode == "values" else stream_mode
   3371         ),
   3372         print_mode=print_mode,
   3373         output_keys=output_keys,
   3374         interrupt_before=interrupt_before,
   3375         interrupt_after=interrupt_after,
   3376         durability=durability,
   3377         **kwargs,
   3378     ):
   3379         if stream_mode == "values":
   3380             if len(chunk) == 2:

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langgraph/pregel/main.py:2759, in Pregel.stream(self, input, config, context, stream_mode, print_mode, output_keys, interrupt_before, interrupt_after, durability, subgraphs, debug, version, **kwargs)
   2757 for task in loop.match_cached_writes():
   2758     loop.output_writes(task.id, task.writes, cached=True)
-> 2759 for _ in runner.tick(
   2760     [t for t in loop.tasks.values() if not t.writes],
   2761     timeout=self.step_timeout,
   2762     get_waiter=get_waiter,
   2763     schedule_task=loop.accept_push,
   2764 ):
   2765     # emit output
   2766     yield from _output(
   2767         stream_mode,
   2768         print_mode,
   (...)   2774         _state_mapper,
   2775     )
   2776 loop.after_tick()

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langgraph/pregel/_runner.py:167, in PregelRunner.tick(self, tasks, reraise, timeout, retry_policy, get_waiter, schedule_task)
    165 t = tasks[0]
    166 try:
--> 167     run_with_retry(
    168         t,
    169         retry_policy,
    170         configurable={
    171             CONFIG_KEY_CALL: partial(
    172                 _call,
    173                 weakref.ref(t),
    174                 retry_policy=retry_policy,
    175                 futures=weakref.ref(futures),
    176                 schedule_task=schedule_task,
    177                 submit=self.submit,
    178             ),
    179         },
    180     )
    181     self.commit(t, None)
    182 except Exception as exc:

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langgraph/pregel/_retry.py:126, in run_with_retry(task, retry_policy, configurable)
    124     task.writes.clear()
    125     # run the task
--> 126     return task.proc.invoke(task.input, config)
    127 except ParentCommand as exc:
    128     ns: str = config[CONF][CONFIG_KEY_CHECKPOINT_NS]

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langgraph/_internal/_runnable.py:656, in RunnableSeq.invoke(self, input, config, **kwargs)
    654     # run in context
    655     with set_config_context(config, run) as context:
--> 656         input = context.run(step.invoke, input, config, **kwargs)
    657 else:
    658     input = step.invoke(input, config)

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langgraph/_internal/_runnable.py:400, in RunnableCallable.invoke(self, input, config, **kwargs)
    398         run_manager.on_chain_end(ret)
    399 else:
--> 400     ret = self.func(*args, **kwargs)
    401 if self.recurse and isinstance(ret, Runnable):
    402     return ret.invoke(input, config)

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain/agents/factory.py:1310, in create_agent.<locals>.model_node(state, runtime)
   1298 request = ModelRequest(
   1299     model=model,
   1300     tools=default_tools,
   (...)   1306     runtime=runtime,
   1307 )
   1309 if wrap_model_call_handler is None:
-> 1310     model_response = _execute_model_sync(request)
   1311     return _build_commands(model_response)
   1313 result = wrap_model_call_handler(request, _execute_model_sync)

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain/agents/factory.py:1282, in create_agent.<locals>._execute_model_sync(request)
   1279 if request.system_message:
   1280     messages = [request.system_message, *messages]
-> 1282 output = model_.invoke(messages)
   1283 if name:
   1284     output.name = name

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain_core/runnables/base.py:5695, in RunnableBindingBase.invoke(self, input, config, **kwargs)
   5688 @override
   5689 def invoke(
   5690     self,
   (...)   5693     **kwargs: Any | None,
   5694 ) -> Output:
-> 5695     return self.bound.invoke(
   5696         input,
   5697         self._merge_configs(config),
   5698         **{**self.kwargs, **kwargs},
   5699     )

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain_core/language_models/chat_models.py:455, in BaseChatModel.invoke(self, input, config, stop, **kwargs)
    441 @override
    442 def invoke(
    443     self,
   (...)    448     **kwargs: Any,
    449 ) -> AIMessage:
    450     config = ensure_config(config)
    451     return cast(
    452         "AIMessage",
    453         cast(
    454             "ChatGeneration",
--> 455             self.generate_prompt(
    456                 [self._convert_input(input)],
    457                 stop=stop,
    458                 callbacks=config.get("callbacks"),
    459                 tags=config.get("tags"),
    460                 metadata=config.get("metadata"),
    461                 run_name=config.get("run_name"),
    462                 run_id=config.pop("run_id", None),
    463                 **kwargs,
    464             ).generations[0][0],
    465         ).message,
    466     )

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain_core/language_models/chat_models.py:1198, in BaseChatModel.generate_prompt(self, prompts, stop, callbacks, **kwargs)
   1189 @override
   1190 def generate_prompt(
   1191     self,
   (...)   1195     **kwargs: Any,
   1196 ) -> LLMResult:
   1197     prompt_messages = [p.to_messages() for p in prompts]
-> 1198     return self.generate(prompt_messages, stop=stop, callbacks=callbacks, **kwargs)

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain_core/language_models/chat_models.py:1005, in BaseChatModel.generate(self, messages, stop, callbacks, tags, metadata, run_name, run_id, **kwargs)
   1002 for i, m in enumerate(input_messages):
   1003     try:
   1004         results.append(
-> 1005             self._generate_with_cache(
   1006                 m,
   1007                 stop=stop,
   1008                 run_manager=run_managers[i] if run_managers else None,
   1009                 **kwargs,
   1010             )
   1011         )
   1012     except BaseException as e:
   1013         if run_managers:

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain_core/language_models/chat_models.py:1310, in BaseChatModel._generate_with_cache(self, messages, stop, run_manager, **kwargs)
   1308     result = generate_from_stream(iter(chunks))
   1309 elif inspect.signature(self._generate).parameters.get("run_manager"):
-> 1310     result = self._generate(
   1311         messages, stop=stop, run_manager=run_manager, **kwargs
   1312     )
   1313 else:
   1314     result = self._generate(messages, stop=stop, **kwargs)

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain_anthropic/chat_models.py:1566, in ChatAnthropic._generate(self, messages, stop, run_manager, **kwargs)
   1564     data = self._create(payload)
   1565 except anthropic.BadRequestError as e:
-> 1566     _handle_anthropic_bad_request(e)
   1567 return self._format_output(data, **kwargs)

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain_anthropic/chat_models.py:1564, in ChatAnthropic._generate(self, messages, stop, run_manager, **kwargs)
   1562 payload = self._get_request_payload(messages, stop=stop, **kwargs)
   1563 try:
-> 1564     data = self._create(payload)
   1565 except anthropic.BadRequestError as e:
   1566     _handle_anthropic_bad_request(e)

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain_anthropic/chat_models.py:1228, in ChatAnthropic._create(self, payload)
   1226 def _create(self, payload: dict) -> Any:
   1227     if "betas" in payload:
-> 1228         return self._client.beta.messages.create(**payload)
   1229     return self._client.messages.create(**payload)

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/anthropic/_utils/_utils.py:283, in required_args.<locals>.inner.<locals>.wrapper(*args, **kwargs)
    281             msg = f"Missing required argument: {quote(missing[0])}"
    282     raise TypeError(msg)
--> 283 return func(*args, **kwargs)

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/anthropic/resources/beta/messages/messages.py:1100, in Messages.create(self, max_tokens, messages, model, cache_control, container, context_management, inference_geo, mcp_servers, metadata, output_config, output_format, service_tier, speed, stop_sequences, stream, system, temperature, thinking, tool_choice, tools, top_k, top_p, user_profile_id, betas, extra_headers, extra_query, extra_body, timeout)
   1093 merged_output_config = _merge_output_configs(output_config, output_format)
   1095 extra_headers = {
   1096     **strip_not_given({"anthropic-beta": ",".join(str(e) for e in betas) if is_given(betas) else not_given}),
   1097     **_stainless_helper_header(tools, messages),
   1098     **(extra_headers or {}),
   1099 }
-> 1100 return self._post(
   1101     "/v1/messages?beta=true",
   1102     body=maybe_transform(
   1103         {
   1104             "max_tokens": max_tokens,
   1105             "messages": messages,
   1106             "model": model,
   1107             "cache_control": cache_control,
   1108             "container": container,
   1109             "context_management": context_management,
   1110             "inference_geo": inference_geo,
   1111             "mcp_servers": mcp_servers,
   1112             "metadata": metadata,
   1113             "output_config": merged_output_config,
   1114             "output_format": omit,
   1115             "service_tier": service_tier,
   1116             "speed": speed,
   1117             "stop_sequences": stop_sequences,
   1118             "stream": stream,
   1119             "system": system,
   1120             "temperature": temperature,
   1121             "thinking": thinking,
   1122             "tool_choice": tool_choice,
   1123             "tools": tools,
   1124             "top_k": top_k,
   1125             "top_p": top_p,
   1126             "user_profile_id": user_profile_id,
   1127         },
   1128         message_create_params.MessageCreateParamsStreaming
   1129         if stream
   1130         else message_create_params.MessageCreateParamsNonStreaming,
   1131     ),
   1132     options=make_request_options(
   1133         extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
   1134     ),
   1135     cast_to=BetaMessage,
   1136     stream=stream or False,
   1137     stream_cls=Stream[BetaRawMessageStreamEvent],
   1138 )

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/anthropic/_base_client.py:1368, in SyncAPIClient.post(self, path, cast_to, body, content, options, files, stream, stream_cls)
   1359     warnings.warn(
   1360         "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
   1361         "Please pass raw bytes via the `content` parameter instead.",
   1362         DeprecationWarning,
   1363         stacklevel=2,
   1364     )
   1365 opts = FinalRequestOptions.construct(
   1366     method="post", url=path, json_data=body, content=content, files=to_httpx_files(files), **options
   1367 )
-> 1368 return cast(ResponseT, self.request(cast_to, opts, stream=stream, stream_cls=stream_cls))

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/anthropic/_base_client.py:1141, in SyncAPIClient.request(self, cast_to, options, stream, stream_cls)
   1138             err.response.read()
   1140         log.debug("Re-raising status error")
-> 1141         raise self._make_status_error_from_response(err.response) from None
   1143     break
   1145 assert response is not None, "could not resolve response (should never happen)"

BadRequestError: Error code: 400 - {'type': 'error', 'error': {'type': 'invalid_request_error', 'message': 'messages.63.content.0.compaction.index: Extra inputs are not permitted'}, 'request_id': 'req_011CaMEooKTSiAAWiBiYo2yL'}
During task with name 'model' and id '62a7431b-3f32-e2e5-fbdf-1040c1bf2015'

---

elif block["type"] == "compaction":
                        content.append(
                            {
                                k: v
                                for k, v in block.items()
                                if k in ("type", "content", "cache_control")
                            },
                        )
RAW_BUFFERClick to expand / collapse

Submission checklist

  • This is a bug, not a usage question.
  • I added a clear and descriptive title that summarizes this issue.
  • I used the GitHub search to find a similar question and didn't find it.
  • I am sure that this is a bug in LangChain rather than my code.
  • The bug is not resolved by updating to the latest stable version of LangChain (or the specific integration package).
  • This is not related to the langchain-community package.
  • I posted a self-contained, minimal, reproducible example. A maintainer can copy it and run it AS IS.

Package (Required)

  • langchain
  • langchain-openai
  • langchain-anthropic
  • langchain-classic
  • langchain-core
  • langchain-model-profiles
  • langchain-tests
  • langchain-text-splitters
  • langchain-chroma
  • langchain-deepseek
  • langchain-exa
  • langchain-fireworks
  • langchain-groq
  • langchain-huggingface
  • langchain-mistralai
  • langchain-nomic
  • langchain-ollama
  • langchain-openrouter
  • langchain-perplexity
  • langchain-qdrant
  • langchain-xai
  • Other / not sure / general

Related Issues / PRs

No response

Reproduction Steps / Example Code (Python)

import anthropic

from langchain.agents import create_agent
from langchain_anthropic import ChatAnthropic
from langchain_core.messages import HumanMessage

model = ChatAnthropic(
    model="claude-sonnet-4-6",
    betas=["compact-2026-01-12"],
    max_tokens=8000,
    context_management={
        "edits": [
            {
                "type": "compact_20260112",
                "trigger": {"type": "input_tokens", "value": 50000},
            }
        ]
    },
)

agent = create_agent(
    model=model,
)

client = anthropic.Anthropic()

SYSTEM_MESSAGE = "You are a helpful assistant that answers questions thoroughly and in great detail."

FILLER_PARAGRAPH = FILLER_PARAGRAPH = (
    "Brand24 is a social listening and media monitoring platform that helps businesses track "
    "online mentions of their brand, products, and competitors across social media, news sites, "
    "blogs, forums, podcasts, and more. The platform provides real-time alerts, sentiment analysis, "
    "influencer identification, and detailed analytics to help companies understand their online "
    "presence and make data-driven marketing decisions. With Brand24, users can monitor keywords, "
    "hashtags, and phrases across millions of online sources, gaining valuable insights into "
    "customer opinions, industry trends, and competitive landscape. The tool offers features like "
    "automated reports, discussion volume charts, mention analytics, and integration with popular "
    "business tools. Companies use Brand24 to protect their reputation, measure campaign "
    "effectiveness, find sales leads, and improve customer service by responding quickly to "
    "online conversations about their brand."
) * 5

N = 31

history = []
for i in range(N):
    history.append({"role": "user", "content": f"Question {i+1}: Tell me more about topic number {i+1}. {FILLER_PARAGRAPH}"})
    history.append({"role": "assistant", "content": f"Answer {i+1}: Here is a detailed response about topic {i+1}. {FILLER_PARAGRAPH}"})
history.append({"role": "user", "content": "Hi, my name is John"})

token_count = client.messages.count_tokens(
    model="claude-sonnet-4-6",
    system=SYSTEM_MESSAGE,
    messages=history,
)
assert token_count.input_tokens > 50_000, f"Expected >50k tokens, got {token_count.input_tokens:,}"
assert token_count.input_tokens < 60_000, f"Expected <60k tokens, got {token_count.input_tokens:,}"

# The first request triggers compaction. With print_mode="updates" everything is fine
result = agent.invoke({"messages": history}, print_mode="updates")
result2 = agent.invoke({"messages": result["messages"] + [HumanMessage(content="What is my name?")]}, print_mode="updates")

# Now we make the first request with print_mode="messages". The second request produce an error
result = agent.invoke({"messages": history}, print_mode="messages")  # Works fine
result2 = agent.invoke({"messages": result["messages"] + [HumanMessage(content="What is my name?")]}, print_mode=("messages"))  # Produces an error

Error Message and Stack Trace (if applicable)

---------------------------------------------------------------------------
BadRequestError                           Traceback (most recent call last)
Cell In[20], line 3
      1 from langchain_core.messages import HumanMessage
      2 
----> 3 result2 = agent.invoke({"messages": result["messages"] + [HumanMessage(content="What is my name?")]}, print_mode=("messages"))

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langgraph/pregel/main.py:3365, in Pregel.invoke(self, input, config, context, stream_mode, print_mode, output_keys, interrupt_before, interrupt_after, durability, version, **kwargs)
   3362             chunks.append(chunk)
   3363 else:
   3364     # v1: collect interrupts from updates stream
-> 3365     for chunk in self.stream(
   3366         input,
   3367         config,
   3368         context=context,
   3369         stream_mode=(
   3370             ["updates", "values"] if stream_mode == "values" else stream_mode
   3371         ),
   3372         print_mode=print_mode,
   3373         output_keys=output_keys,
   3374         interrupt_before=interrupt_before,
   3375         interrupt_after=interrupt_after,
   3376         durability=durability,
   3377         **kwargs,
   3378     ):
   3379         if stream_mode == "values":
   3380             if len(chunk) == 2:

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langgraph/pregel/main.py:2759, in Pregel.stream(self, input, config, context, stream_mode, print_mode, output_keys, interrupt_before, interrupt_after, durability, subgraphs, debug, version, **kwargs)
   2757 for task in loop.match_cached_writes():
   2758     loop.output_writes(task.id, task.writes, cached=True)
-> 2759 for _ in runner.tick(
   2760     [t for t in loop.tasks.values() if not t.writes],
   2761     timeout=self.step_timeout,
   2762     get_waiter=get_waiter,
   2763     schedule_task=loop.accept_push,
   2764 ):
   2765     # emit output
   2766     yield from _output(
   2767         stream_mode,
   2768         print_mode,
   (...)   2774         _state_mapper,
   2775     )
   2776 loop.after_tick()

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langgraph/pregel/_runner.py:167, in PregelRunner.tick(self, tasks, reraise, timeout, retry_policy, get_waiter, schedule_task)
    165 t = tasks[0]
    166 try:
--> 167     run_with_retry(
    168         t,
    169         retry_policy,
    170         configurable={
    171             CONFIG_KEY_CALL: partial(
    172                 _call,
    173                 weakref.ref(t),
    174                 retry_policy=retry_policy,
    175                 futures=weakref.ref(futures),
    176                 schedule_task=schedule_task,
    177                 submit=self.submit,
    178             ),
    179         },
    180     )
    181     self.commit(t, None)
    182 except Exception as exc:

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langgraph/pregel/_retry.py:126, in run_with_retry(task, retry_policy, configurable)
    124     task.writes.clear()
    125     # run the task
--> 126     return task.proc.invoke(task.input, config)
    127 except ParentCommand as exc:
    128     ns: str = config[CONF][CONFIG_KEY_CHECKPOINT_NS]

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langgraph/_internal/_runnable.py:656, in RunnableSeq.invoke(self, input, config, **kwargs)
    654     # run in context
    655     with set_config_context(config, run) as context:
--> 656         input = context.run(step.invoke, input, config, **kwargs)
    657 else:
    658     input = step.invoke(input, config)

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langgraph/_internal/_runnable.py:400, in RunnableCallable.invoke(self, input, config, **kwargs)
    398         run_manager.on_chain_end(ret)
    399 else:
--> 400     ret = self.func(*args, **kwargs)
    401 if self.recurse and isinstance(ret, Runnable):
    402     return ret.invoke(input, config)

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain/agents/factory.py:1310, in create_agent.<locals>.model_node(state, runtime)
   1298 request = ModelRequest(
   1299     model=model,
   1300     tools=default_tools,
   (...)   1306     runtime=runtime,
   1307 )
   1309 if wrap_model_call_handler is None:
-> 1310     model_response = _execute_model_sync(request)
   1311     return _build_commands(model_response)
   1313 result = wrap_model_call_handler(request, _execute_model_sync)

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain/agents/factory.py:1282, in create_agent.<locals>._execute_model_sync(request)
   1279 if request.system_message:
   1280     messages = [request.system_message, *messages]
-> 1282 output = model_.invoke(messages)
   1283 if name:
   1284     output.name = name

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain_core/runnables/base.py:5695, in RunnableBindingBase.invoke(self, input, config, **kwargs)
   5688 @override
   5689 def invoke(
   5690     self,
   (...)   5693     **kwargs: Any | None,
   5694 ) -> Output:
-> 5695     return self.bound.invoke(
   5696         input,
   5697         self._merge_configs(config),
   5698         **{**self.kwargs, **kwargs},
   5699     )

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain_core/language_models/chat_models.py:455, in BaseChatModel.invoke(self, input, config, stop, **kwargs)
    441 @override
    442 def invoke(
    443     self,
   (...)    448     **kwargs: Any,
    449 ) -> AIMessage:
    450     config = ensure_config(config)
    451     return cast(
    452         "AIMessage",
    453         cast(
    454             "ChatGeneration",
--> 455             self.generate_prompt(
    456                 [self._convert_input(input)],
    457                 stop=stop,
    458                 callbacks=config.get("callbacks"),
    459                 tags=config.get("tags"),
    460                 metadata=config.get("metadata"),
    461                 run_name=config.get("run_name"),
    462                 run_id=config.pop("run_id", None),
    463                 **kwargs,
    464             ).generations[0][0],
    465         ).message,
    466     )

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain_core/language_models/chat_models.py:1198, in BaseChatModel.generate_prompt(self, prompts, stop, callbacks, **kwargs)
   1189 @override
   1190 def generate_prompt(
   1191     self,
   (...)   1195     **kwargs: Any,
   1196 ) -> LLMResult:
   1197     prompt_messages = [p.to_messages() for p in prompts]
-> 1198     return self.generate(prompt_messages, stop=stop, callbacks=callbacks, **kwargs)

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain_core/language_models/chat_models.py:1005, in BaseChatModel.generate(self, messages, stop, callbacks, tags, metadata, run_name, run_id, **kwargs)
   1002 for i, m in enumerate(input_messages):
   1003     try:
   1004         results.append(
-> 1005             self._generate_with_cache(
   1006                 m,
   1007                 stop=stop,
   1008                 run_manager=run_managers[i] if run_managers else None,
   1009                 **kwargs,
   1010             )
   1011         )
   1012     except BaseException as e:
   1013         if run_managers:

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain_core/language_models/chat_models.py:1310, in BaseChatModel._generate_with_cache(self, messages, stop, run_manager, **kwargs)
   1308     result = generate_from_stream(iter(chunks))
   1309 elif inspect.signature(self._generate).parameters.get("run_manager"):
-> 1310     result = self._generate(
   1311         messages, stop=stop, run_manager=run_manager, **kwargs
   1312     )
   1313 else:
   1314     result = self._generate(messages, stop=stop, **kwargs)

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain_anthropic/chat_models.py:1566, in ChatAnthropic._generate(self, messages, stop, run_manager, **kwargs)
   1564     data = self._create(payload)
   1565 except anthropic.BadRequestError as e:
-> 1566     _handle_anthropic_bad_request(e)
   1567 return self._format_output(data, **kwargs)

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain_anthropic/chat_models.py:1564, in ChatAnthropic._generate(self, messages, stop, run_manager, **kwargs)
   1562 payload = self._get_request_payload(messages, stop=stop, **kwargs)
   1563 try:
-> 1564     data = self._create(payload)
   1565 except anthropic.BadRequestError as e:
   1566     _handle_anthropic_bad_request(e)

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/langchain_anthropic/chat_models.py:1228, in ChatAnthropic._create(self, payload)
   1226 def _create(self, payload: dict) -> Any:
   1227     if "betas" in payload:
-> 1228         return self._client.beta.messages.create(**payload)
   1229     return self._client.messages.create(**payload)

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/anthropic/_utils/_utils.py:283, in required_args.<locals>.inner.<locals>.wrapper(*args, **kwargs)
    281             msg = f"Missing required argument: {quote(missing[0])}"
    282     raise TypeError(msg)
--> 283 return func(*args, **kwargs)

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/anthropic/resources/beta/messages/messages.py:1100, in Messages.create(self, max_tokens, messages, model, cache_control, container, context_management, inference_geo, mcp_servers, metadata, output_config, output_format, service_tier, speed, stop_sequences, stream, system, temperature, thinking, tool_choice, tools, top_k, top_p, user_profile_id, betas, extra_headers, extra_query, extra_body, timeout)
   1093 merged_output_config = _merge_output_configs(output_config, output_format)
   1095 extra_headers = {
   1096     **strip_not_given({"anthropic-beta": ",".join(str(e) for e in betas) if is_given(betas) else not_given}),
   1097     **_stainless_helper_header(tools, messages),
   1098     **(extra_headers or {}),
   1099 }
-> 1100 return self._post(
   1101     "/v1/messages?beta=true",
   1102     body=maybe_transform(
   1103         {
   1104             "max_tokens": max_tokens,
   1105             "messages": messages,
   1106             "model": model,
   1107             "cache_control": cache_control,
   1108             "container": container,
   1109             "context_management": context_management,
   1110             "inference_geo": inference_geo,
   1111             "mcp_servers": mcp_servers,
   1112             "metadata": metadata,
   1113             "output_config": merged_output_config,
   1114             "output_format": omit,
   1115             "service_tier": service_tier,
   1116             "speed": speed,
   1117             "stop_sequences": stop_sequences,
   1118             "stream": stream,
   1119             "system": system,
   1120             "temperature": temperature,
   1121             "thinking": thinking,
   1122             "tool_choice": tool_choice,
   1123             "tools": tools,
   1124             "top_k": top_k,
   1125             "top_p": top_p,
   1126             "user_profile_id": user_profile_id,
   1127         },
   1128         message_create_params.MessageCreateParamsStreaming
   1129         if stream
   1130         else message_create_params.MessageCreateParamsNonStreaming,
   1131     ),
   1132     options=make_request_options(
   1133         extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
   1134     ),
   1135     cast_to=BetaMessage,
   1136     stream=stream or False,
   1137     stream_cls=Stream[BetaRawMessageStreamEvent],
   1138 )

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/anthropic/_base_client.py:1368, in SyncAPIClient.post(self, path, cast_to, body, content, options, files, stream, stream_cls)
   1359     warnings.warn(
   1360         "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
   1361         "Please pass raw bytes via the `content` parameter instead.",
   1362         DeprecationWarning,
   1363         stacklevel=2,
   1364     )
   1365 opts = FinalRequestOptions.construct(
   1366     method="post", url=path, json_data=body, content=content, files=to_httpx_files(files), **options
   1367 )
-> 1368 return cast(ResponseT, self.request(cast_to, opts, stream=stream, stream_cls=stream_cls))

File ~/ai24/dist/export/python/virtualenvs/langchain_compaction_test/lib/python3.12/site-packages/anthropic/_base_client.py:1141, in SyncAPIClient.request(self, cast_to, options, stream, stream_cls)
   1138             err.response.read()
   1140         log.debug("Re-raising status error")
-> 1141         raise self._make_status_error_from_response(err.response) from None
   1143     break
   1145 assert response is not None, "could not resolve response (should never happen)"

BadRequestError: Error code: 400 - {'type': 'error', 'error': {'type': 'invalid_request_error', 'message': 'messages.63.content.0.compaction.index: Extra inputs are not permitted'}, 'request_id': 'req_011CaMEooKTSiAAWiBiYo2yL'}
During task with name 'model' and id '62a7431b-3f32-e2e5-fbdf-1040c1bf2015'

Description

I am trying to use streaming with "messages" mode for my agent with custom tools and compaction for context management.

It appears that the index field produced by the LangChain during "messages" mode streaming is not stripped off and result in the error in the subsequent Anthropic API request. I have seen it multiple times when my agent first performed compaction and then used any of my custom tool which resulted in a new request to Anthropic API and a corresponding "Extra inputs are not permitted" error. I managed to reproduced it in minimal, reliable example by using print_mode="messages" in agent.invoke() and handcrafted messages.

I don't know LangChain internals too well, but in my experiments it looked like the "index" field is required for "messages" streaming mode. I think the best solution would be to add a dedicated block for formatting compaction blocks in _format_messages function of langchain_anthropic/chat_models.py that formats LangChain messages before sending them to the Anthropic API:

                    elif block["type"] == "compaction":
                        content.append(
                            {
                                k: v
                                for k, v in block.items()
                                if k in ("type", "content", "cache_control")
                            },
                        )

I think this is clean and shouldn't break anything as it only strips extra fields from compaction blocks sent to the Anthropic API

System Info

System Information

OS: Linux OS Version: #1 SMP PREEMPT_DYNAMIC Wed Feb 12 05:52:18 EST 2025 Python Version: 3.12.6 (main, Sep 27 2024, 06:10:12) [GCC 12.2.0]

Package Information

langchain_core: 1.3.0 langchain: 1.2.15 langsmith: 0.7.34 langchain_anthropic: 1.4.1 langgraph_sdk: 0.3.13

Optional packages not installed

deepagents deepagents-cli

Other Dependencies

anthropic: 0.96.0 httpx: 0.28.1 jsonpatch: 1.33 langgraph: 1.1.9 orjson: 3.11.8 packaging: 26.1 pydantic: 2.13.3 pyyaml: 6.0.3 requests: 2.33.1 requests-toolbelt: 1.0.0 tenacity: 9.1.4 typing-extensions: 4.15.0 uuid-utils: 0.14.1 xxhash: 3.6.0 zstandard: 0.25.0

extent analysis

TL;DR

The issue can be fixed by modifying the _format_messages function in langchain_anthropic/chat_models.py to strip extra fields from compaction blocks sent to the Anthropic API.

Guidance

  • Identify the _format_messages function in langchain_anthropic/chat_models.py and add a dedicated block for formatting compaction blocks.
  • Modify the function to strip extra fields from compaction blocks, specifically the "index" field, when sending messages to the Anthropic API.
  • Test the modified function with the provided minimal example to verify the fix.
  • Consider submitting a pull request to the LangChain repository with the proposed fix.

Example

elif block["type"] == "compaction":
    content.append(
        {
            k: v
            for k, v in block.items()
            if k in ("type", "content", "cache_control")
        },
    )

Notes

  • The proposed fix assumes that the "index" field is not required for the Anthropic API request.
  • The modification should be made in the langchain_anthropic package, specifically in the chat_models.py file.
  • The fix may need to be adapted based on the specific requirements of the Anthropic API and the LangChain library.

Recommendation

Apply the proposed workaround by modifying the _format_messages function to strip extra fields from compaction blocks. This should resolve the "Extra inputs are not permitted" error when using streaming with "messages" mode.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING