Extended thinking blocks not preserved during tool use loops causing 400 error
Description
When using the Claude Agent SDK with models that have extended thinking enabled (e.g., claude-opus-4-5-20251101), tool use loops fail with a 400 error because thinking blocks are not being preserved in the conversation history.
Error Message
Error: 400 {"type":"error","error":{"type":"invalid_request_error","message":"messages.47.content.0.type: Expected thinking or redacted_thinking, but found tool_use. When thinking is enabled, a final assistant message must start with a thinking block (preceeding the lastmost set of tool_use and tool_result blocks). We recommend you include thinking blocks from previous turns. To avoid this requirement, disable thinking. Please consult our documentation at https://docs.claude.com/en/docs/build-with-claude/extended-thinking"},"request_id":"req_011CWBSTUXmhrbVveBY3uobN"}
Environment
- SDK:
@anthropic-ai/claude-agent-sdkversion 0.1.69 - Model:
claude-opus-4-5-20251101 - Mode: Streaming input mode with
query()and AsyncGenerator
Reproduction
- Create a query using streaming input mode:
import { query } from '@anthropic-ai/claude-agent-sdk';
const queryObject = query({
prompt: messageGenerator(), // AsyncGenerator yielding user messages
options: {
model: 'claude-opus-4-5-20251101',
cwd: '/path/to/workspace',
// ... other options
},
});
for await (const message of queryObject) {
// Process SDK messages
}
- Send messages that trigger tool use (e.g., file operations, web searches)
- After multiple tool use rounds (around message 47 in our case), the error occurs
Expected Behavior
The SDK should automatically preserve thinking and redacted_thinking blocks from assistant messages when constructing the conversation history for subsequent API calls during tool use loops.
According to the official documentation:
"During tool use, you must pass thinking blocks back to the API for the last assistant message. Include the complete unmodified block back to the API to maintain reasoning continuity."
Since the SDK manages the conversation state internally when using query(), users have no way to manually preserve these blocks.
Actual Behavior
The SDK appears to strip or not include thinking blocks when reconstructing assistant messages for the API, causing the validation error when extended thinking is enabled.
Workaround
Currently no workaround is available when using streaming input mode, as the SDK handles the message history internally.
Additional Context
- The error occurs at
messages.47, indicating this happens in longer conversations with multiple tool use cycles - The issue is specific to models with extended thinking enabled by default (Claude Opus 4.5, etc.)
- This affects applications that use the SDK's high-level
query()API rather than manual message construction
Related Documentation
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗