Commit 5230482
authored
fix(ai): Don't create duplicate tool parts when models call non-existent tools (#12774)
## Background
When a model calls a tool that doesn't exist in the tools object (e.g. a
hallucinated tool name), processUIMessageStream creates two message
parts for the same toolCallId — one static (tool-{toolName}) and one
dynamic (dynamic-tool). This causes downstream failures when the
conversation is continued, since the model API rejects requests
containing two tool results for the same tool call ID.
## Summary
Fixes a bug in `processUIMessageStream` where a model calling a
non-existent tool produces two UI message parts for the same
`toolCallId` — one static (`tool-{toolName}`) and one dynamic
(`dynamic-tool`). This happens because `tool-input-start` creates a
static part (when `dynamic` is undefined for an unknown tool), but the
subsequent `tool-input-error` arrives with `dynamic: true` and only
searches for a `dynamic-tool` part, missing the existing static one and
creating a duplicate. The fix checks for an existing part by
`toolCallId` before branching on `chunk.dynamic`, so the error updates
the existing part in place instead of creating a second one.
## Manual Verification
Manually verified against my own application. After the fix, I got a
single tool part like:
```
{
"type": "tool-dashboard-page-create-dashboard",
"state": "output-error",
"rawInput":
{
"name": "Staging Monitoring"
},
"errorText": "Model tried to call unavailable tool 'dashboard-page-create-dashboard'. Available tools: ....",
"toolCallId": "toolu_015E6Kd6cwSMkw7SFpsa7w88",
"callProviderMetadata":
{
"anthropic":
{
"caller":
{
"type": "direct"
}
}
}
},
```
## Checklist
- [x] Tests have been added / updated (for bug fixes / features)
- [ ] Documentation has been added / updated (for bug fixes / features)
- [x] A _patch_ changeset for relevant packages has been added (for bug
fixes / features - run `pnpm changeset` in the project root)
- [x] I have reviewed this pull request (self-review)
## Related Issues
Fixes #127721 parent 032d9a3 commit 5230482
File tree
3 files changed
+119
-1
lines changed- .changeset
- packages/ai/src/ui
3 files changed
+119
-1
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6433 | 6433 | | |
6434 | 6434 | | |
6435 | 6435 | | |
| 6436 | + | |
| 6437 | + | |
| 6438 | + | |
| 6439 | + | |
| 6440 | + | |
| 6441 | + | |
| 6442 | + | |
| 6443 | + | |
| 6444 | + | |
| 6445 | + | |
| 6446 | + | |
| 6447 | + | |
| 6448 | + | |
| 6449 | + | |
| 6450 | + | |
| 6451 | + | |
| 6452 | + | |
| 6453 | + | |
| 6454 | + | |
| 6455 | + | |
| 6456 | + | |
| 6457 | + | |
| 6458 | + | |
| 6459 | + | |
| 6460 | + | |
| 6461 | + | |
| 6462 | + | |
| 6463 | + | |
| 6464 | + | |
| 6465 | + | |
| 6466 | + | |
| 6467 | + | |
| 6468 | + | |
| 6469 | + | |
| 6470 | + | |
| 6471 | + | |
| 6472 | + | |
| 6473 | + | |
| 6474 | + | |
| 6475 | + | |
| 6476 | + | |
| 6477 | + | |
| 6478 | + | |
| 6479 | + | |
| 6480 | + | |
| 6481 | + | |
| 6482 | + | |
| 6483 | + | |
| 6484 | + | |
| 6485 | + | |
| 6486 | + | |
| 6487 | + | |
| 6488 | + | |
| 6489 | + | |
| 6490 | + | |
| 6491 | + | |
| 6492 | + | |
| 6493 | + | |
| 6494 | + | |
| 6495 | + | |
| 6496 | + | |
| 6497 | + | |
| 6498 | + | |
| 6499 | + | |
| 6500 | + | |
| 6501 | + | |
| 6502 | + | |
| 6503 | + | |
| 6504 | + | |
| 6505 | + | |
| 6506 | + | |
| 6507 | + | |
| 6508 | + | |
| 6509 | + | |
| 6510 | + | |
| 6511 | + | |
| 6512 | + | |
| 6513 | + | |
| 6514 | + | |
| 6515 | + | |
| 6516 | + | |
| 6517 | + | |
| 6518 | + | |
| 6519 | + | |
| 6520 | + | |
| 6521 | + | |
| 6522 | + | |
| 6523 | + | |
| 6524 | + | |
| 6525 | + | |
| 6526 | + | |
| 6527 | + | |
| 6528 | + | |
| 6529 | + | |
| 6530 | + | |
| 6531 | + | |
| 6532 | + | |
| 6533 | + | |
| 6534 | + | |
| 6535 | + | |
| 6536 | + | |
| 6537 | + | |
6436 | 6538 | | |
6437 | 6539 | | |
6438 | 6540 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
558 | 558 | | |
559 | 559 | | |
560 | 560 | | |
561 | | - | |
| 561 | + | |
| 562 | + | |
| 563 | + | |
| 564 | + | |
| 565 | + | |
| 566 | + | |
| 567 | + | |
| 568 | + | |
| 569 | + | |
| 570 | + | |
| 571 | + | |
| 572 | + | |
562 | 573 | | |
563 | 574 | | |
564 | 575 | | |
| |||
0 commit comments