AI & Agent Dev Bug Sandbox logo
AI & Agent Dev Bug Sandbox
Back to Radar

ChatAnthropic Streaming On Thinking-By-Default Models Produces Malformed Content And Replays Cause 400

Streaming with ChatAnthropic on models like claude-opus-5 or claude-sonnet-5 (where thinking runs by default) yields a mixed list containing an empty string, leading to an empty text block when replayed, and the Anthropic API rejects the request with a 400 invalid_request_error.

highConfidence 90%LangchainAffected V1.5.6

Origin Analysis

Two-part root cause: 1) _thinking_in_params inspects only the request payload. When thinking is omitted, _stream/_astream set coerce_content_to_string=True, causing message_start to emit content='' and text deltas as bare strings, while thinking blocks are emitted as dicts unconditionally. merge_content then yields ['', {thinking...}, 'text']. 2) When that message is sent back, the string item is converted to a text block without an emptiness check, whereas the dict-text branch below guards with if text.strip():. The empty string becomes an empty text block, and the API rejects it.
1. Instantiate ChatAnthropic(model='claude-opus-5') 2. Stream a simple prompt: for chunk in llm.stream('In one word, what is the capital of France?'): accumulate chunks. 3. Inspect final.content -> ['', {'type': 'thinking', ...}, 'Paris'] 4. Invoke a second turn including the accumulated message: llm.invoke([('human', '...'), final, ('human', '...')]) 5. Observe anthropic.BadRequestError: 400 with message 'messages: text content blocks must be non-empty'

Fixing Code Block

Edge Case Audit

This changes streaming coercion behavior for all Anthropic models. If the model-aware detection list is incomplete or new thinking-by-default models are released, the issue may recur. The empty string guard could theoretically drop a legitimate empty text block, but that is unlikely. Rollback: revert the coerce_content_to_string change and keep the .strip() guard only; or explicitly pass thinking parameters as a workaround. Test with explicit thinking enabled/disabled, and with multi-turn streaming on affected and unaffected models.

Ecosystem Topology