Repository navigation
fix: Incomplete and malformed tool-call part in conversation - #679
Conversation
…t to avoid malformed tool call persistance
📝 WalkthroughWalkthroughThe PR refines tool handling in the AI core pipeline. Message sanitization now filters tool-call parts whose tool names are unavailable, incomplete error tool calls are repaired with backfilled input, available tool names are wired through the streaming transport layer, and sub-agent error handling synchronizes pending tool-call state earlier in the failure path. ChangesTool Availability Filtering and Error Handling
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/ai-core/src/utils.ts (1)
511-527: 💤 Low valueConsider handling non-object
rawInputvalues.The backfill
toolPart.rawInput ?? {}assumesrawInputis eitherundefinedor an object. IfrawInputis a primitive (e.g., a malformed string from a hallucinated tool call), passing it directly asinputcould cause downstream issues if consumers expect an object.However, looking at the broader context, this fallback to
{}whenrawInputis falsy is reasonable, and the AI SDK's schema validation would catch truly malformed inputs. The fix addresses the immediate "input: Value: undefined" validation failure.Optional: Defensive coercion to object
if (toolPart.state === 'output-error' && toolPart.input === undefined) { + const backfilledInput = + toolPart.rawInput && typeof toolPart.rawInput === 'object' + ? toolPart.rawInput + : {}; updatedParts[i] = { ...updatedParts[i], - input: toolPart.rawInput ?? {}, + input: backfilledInput, } as (typeof message.parts)[number]; }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/ai-core/src/utils.ts` around lines 511 - 527, The backfill currently assigns toolPart.rawInput ?? {} directly to input, which can propagate primitives; update the branch inside the toolPart.state === 'output-error' check to coerce non-object rawInput into a safe object before assigning to updatedParts[i]. Specifically, when populating input for the updatedParts entry, use toolPart.rawInput if it's a non-null object, otherwise wrap the primitive (e.g., String(toolPart.rawInput) or {raw: toolPart.rawInput}) into an object so input is always an object; modify the logic around toolPart, updatedParts, rawInput and input accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/ai-core/src/utils.ts`:
- Around line 511-527: The backfill currently assigns toolPart.rawInput ?? {}
directly to input, which can propagate primitives; update the branch inside the
toolPart.state === 'output-error' check to coerce non-object rawInput into a
safe object before assigning to updatedParts[i]. Specifically, when populating
input for the updatedParts entry, use toolPart.rawInput if it's a non-null
object, otherwise wrap the primitive (e.g., String(toolPart.rawInput) or {raw:
toolPart.rawInput}) into an object so input is always an object; modify the
logic around toolPart, updatedParts, rawInput and input accordingly.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 8555d7c6-fd53-407e-a007-25b946d8a7fa
📒 Files selected for processing (3)
packages/ai-core/src/agents/AgentUtils.tspackages/ai-core/src/chatTransport.tspackages/ai-core/src/utils.ts
In some cases (e.g. dynamic tool composition), the tool name may be hallucinated. When tool-input parsing fails, the AI SDK emits an output-error part with only rawInput. The incomplete and malformed tool-call part will be persisted in conversation, and it breaks every later request.
This fix is to enhance message sanitization and tool handling in chat transportation to avoid incomplete and malformed tool-call parts.
Summary by CodeRabbit