Commit e06b520
fix: split client/provider tool blocks to fix Anthropic ordering error (#14648)
## Problem
When Anthropic returns `tool_use` (client) before `server_tool_use`
(provider) in the same turn, and the provider result is inlined in the
assistant message, the client `tool_result` doesn't immediately follow
its `tool_use`. Anthropic rejects this with:
> `tool_use ids were found without tool_result blocks immediately after`
This happens non-deterministically when using web_search alongside
client tools (e.g. find_files, execute_command). Once it occurs, the
thread becomes unrecoverable.
## Root cause
`convertToModelMessages` groups consecutive tool parts into a single
assistant message block. When a client tool precedes a provider tool,
the resulting structure is:
```
assistant: [tool_use(client), server_tool_use(provider), web_search_tool_result(provider)]
user: [tool_result(client)]
```
Anthropic requires `tool_result(client)` to **immediately follow**
`tool_use(client)`, but the inlined provider result sits between them.
## Fix
Insert a `step-start` in `addStartStepPartsForAIV5` between client tool
parts and completed provider-executed tool parts. This forces them into
separate message blocks:
```
assistant: [tool_use(client)]
user: [tool_result(client)]
assistant: [server_tool_use(provider), web_search_tool_result(provider)]
```
The reverse order (provider before client) is already safe and is not
split.
## Tests
- 6 unit tests for `addStartStepPartsForAIV5` splitting logic (fail
without fix)
- 1 e2e test with recorded two-turn flow (verified against real
Anthropic API: 400 without fix, passes with fix)
## Test plan
```bash
cd packages/core
pnpm vitest run src/agent/message-list/conversion/output-converter-provider-executed.test.ts
pnpm vitest run src/tools/provider-tools-ordering.e2e.test.ts
```
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Fixed a critical issue where parallel execution of client and provider
tools would cause Anthropic integration to reject requests, making
conversation threads unrecoverable. Tool message handling has been
improved to ensure proper sequencing compatibility with Anthropic's
requirements.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: CalebBarnes <CalebBarnes@users.noreply.github.com>
Co-authored-by: Mastra Code (anthropic/claude-opus-4-6) <noreply@mastra.ai>1 parent c64a081 commit e06b520
5 files changed
Lines changed: 1077 additions & 1 deletion
File tree
- .changeset
- packages/core
- __recordings__
- src
- agent/message-list/conversion
- tools
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
0 commit comments