`@ai-sdk/react` Error: Cannot Read 'text' After MCP Tool Error
Have you encountered the frustrating error "TypeError: Cannot read properties of undefined (reading 'text')" while working with @ai-sdk/react and MCP tools? This error can halt your stream processing and leave you scratching your head. In this article, we'll dive deep into the root cause of this issue, explore the scenarios where it occurs, and provide a comprehensive understanding of how to tackle it.
Understanding the Error
The error message "TypeError: Cannot read properties of undefined (reading 'text')" typically arises when your code attempts to access the text property of an object that is unexpectedly undefined. In the context of @ai-sdk/react and MCP (Model Communication Protocol) tools, this often happens after an MCP tool returns an error response. Let's break down the scenario:
When using @ai-sdk/mcp with @ai-sdk/react, the system expects a result field in the JSON-RPC response from the MCP tool. However, when an error occurs, the MCP tool might return a JSON-RPC error with an error field instead of the expected result. This discrepancy can throw off the subsequent processing steps within @ai-sdk/react, especially when the AI model attempts to call another tool.
The Technical Breakdown
To understand the error, let’s delve into the technical details. The error manifests at a specific line in @ai-sdk/react: @ai-sdk_react.js:21874:15. The stack trace provides further clues:
TypeError: Cannot read properties of undefined (reading 'text')
at @ai-sdk_react.js:21874:15
at @ai-sdk_react.js:22878:17
at Array.<anonymous> (@ai-sdk_react.js:22255:17)
at SerialJobExecutor.processQueue (@ai-sdk_react.js:22246:26)
This trace indicates that the error occurs during the processing of a tool result, specifically when trying to read the text property of a content object. The SerialJobExecutor is responsible for managing the queue of tasks, and the error arises when it tries to process the result from the second tool call after the first one returned an error.
Common Scenarios and Environment
This issue typically surfaces in environments where @ai-sdk/react interacts with MCP servers that may return error responses. A common example is using an Elasticsearch MCP server with ES|QL, where query errors can lead to this issue. Here are the key environment details to keep in mind:
@ai-sdk/mcp: Version 0.0.11@ai-sdk/react: Version 2.0.104ai: Version 5.0.104- Platform: Windows 11 (though this can occur on other platforms as well)
- Node.js: v22.x
Understanding your environment is crucial for diagnosing and resolving this error efficiently. Different versions and platforms may exhibit variations in behavior.
Steps to Reproduce
To better grasp the issue, let’s walk through the steps to reproduce it. This will help you identify if you're facing the same problem and allow you to test potential solutions.
- Set up an MCP server that returns error responses: You'll need an MCP server capable of generating errors. An Elasticsearch MCP server with ES|QL is a practical example. Configure it to return error responses for specific queries.
- Execute a tool call that returns an error: Make an initial tool call that intentionally triggers an error. For instance, submit a malformed ES|QL query.
- The AI model attempts to call another tool: Ensure that after the first error-inducing call, the AI model automatically attempts to call a second tool. This is crucial for triggering the error.
- Error occurs when processing the second tool's result:
The "Cannot read properties of undefined (reading 'text')" error should occur when
@ai-sdk/reactprocesses the result of this second tool call.
By following these steps, you can reliably reproduce the error and validate any fixes you implement.
MCP Log Example and Analysis
Analyzing the MCP logs provides valuable insights into the communication between the client and the server. Here’s an example scenario:
// First tool call - returns error
{"method":"tools/call","params":{"name":"esql","arguments":{"query":"..."}},"jsonrpc":"2.0","id":14}
{"jsonrpc":"2.0","id":14,"error":{"code":-32603,"message":"HTTP status client error (400 Bad Request) for url ..."}}
// Second tool call - server responds correctly
{"method":"tools/call","params":{"name":"list_indices","arguments":{"index_pattern":"*"}},"jsonrpc":"2.0","id":15}
{"jsonrpc":"2.0","id":15,"result":{"content":[{"type":"text","text":"Found 5 indices:"},{"type":"text","text":"[...]"}],"isError":false}}
In this example, the first tool call returns an error, as indicated by the error field in the JSON-RPC response. The second tool call, however, receives a valid response with a result field containing content of type text. Despite the valid response, @ai-sdk/react fails to process the second tool result, leading to the error.
Root Cause Analysis
The core issue seems to lie in how @ai-sdk/react handles error responses within its stream processing logic. When a JSON-RPC error is encountered (i.e., a response with an error field instead of a result field), the internal state of the system may not be correctly updated. This can cause subsequent attempts to access content[].text to fail because the expected data structure is not present.
The intermittent nature of the issue suggests a possible race condition or timing problem. This means the error might not occur every time, making it more challenging to diagnose and fix.
Expected vs. Actual Behavior
It’s crucial to understand the discrepancy between the expected and actual behavior to address the issue effectively.
Expected Behavior
After an MCP tool returns an error response, subsequent tool calls should be processed correctly. The system should handle errors gracefully without disrupting the overall flow.
Actual Behavior
The error "Cannot read properties of undefined (reading 'text')" is thrown, and the stream processing abruptly stops. The UI fails to display the result of the second tool call, leaving the user with incomplete information.
Potential Solutions and Workarounds
While a definitive fix might require changes in the @ai-sdk/react library, there are several strategies you can employ to mitigate the issue.
1. Error Handling in MCP Tool Calls
Implement robust error handling in your MCP tool calls. This involves checking for the presence of the error field in the JSON-RPC response and handling it appropriately. For example, you can log the error, display a user-friendly message, or attempt to retry the call.
async function callMcpTool(toolName, args) {
try {
const response = await mcp.call(toolName, args);
if (response.error) {
console.error(`MCP Tool Error: ${response.error.message}`);
// Handle the error appropriately
return null;
}
return response.result;
} catch (error) {
console.error("Error calling MCP tool:", error);
return null;
}
}
2. State Management Adjustments
Review and adjust the state management within your application to ensure that error responses are correctly handled and that subsequent tool calls don't rely on potentially missing data. This may involve resetting or updating relevant state variables when an error occurs.
3. Retry Mechanism
Implement a retry mechanism for failed tool calls. If a tool call results in an error, you can retry it after a short delay. This can help overcome transient issues or race conditions.
async function retryCall(toolName, args, maxRetries = 3, delay = 1000) {
for (let i = 0; i < maxRetries; i++) {
const result = await callMcpTool(toolName, args);
if (result) {
return result;
}
console.log(`Retrying tool call (attempt ${i + 1})...`);
await new Promise(resolve => setTimeout(resolve, delay));
}
console.error("Max retries reached.");
return null;
}
4. Defensive Coding Practices
Employ defensive coding practices to safeguard against undefined values. Before accessing the text property, ensure that the content array and its elements exist. You can use optional chaining or conditional checks to prevent the error.
const content = response?.result?.content;
if (content && content.length > 0) {
content.forEach(item => {
if (item?.type === 'text') {
console.log(item.text);
}
});
}
Conclusion
The "Cannot read properties of undefined (reading 'text')" error in @ai-sdk/react after an MCP tool error response can be a significant roadblock. However, by understanding the root cause, reproducing the issue, and implementing the strategies discussed, you can effectively mitigate and resolve this problem. Remember to focus on robust error handling, state management, and defensive coding practices to ensure a smoother experience with @ai-sdk/react and MCP tools.
For further information on error handling and best practices in React applications, you can check out the React documentation. This will help you gain a deeper understanding and implement more resilient solutions.