Repository navigation
Description
Description
Despite the fix in #3987, error handling in streamText is still not working as expected in version 4.0.18. The application crashes instead of properly catching and handling API errors, even with proper try/catch blocks in place.
Code example
Current Behavior
When an API error occurs (e.g., 404 Not Found), the error bypasses all error handling mechanisms and crashes the application with an uncaught exception, despite having proper error handling in place.
Error Log
APICallError [AI_APICallError]: Not Found
at /app/node_modules/@ai-sdk/provider-utils/src/response-handler.ts:72:16
at processTicksAndRejections (node:internal/process/task_queues:95:5)
at async postToApi (/app/node_modules/@ai-sdk/provider-utils/src/post-to-api.ts:81:28)
at async OpenAIChatLanguageModel.doStream (/app/node_modules/@ai-sdk/openai/src/openai-chat-language-model.ts:375:50)
at async fn (/app/node_modules/ai/core/generate-text/stream-text.ts:532:25)
at async /app/node_modules/ai/core/telemetry/record-span.ts:18:22
at async _retryWithExponentialBackoff (/app/node_modules/ai/util/retry-with-exponential-backoff.ts:37:12)
at async streamStep (/app/node_modules/ai/core/generate-text/stream-text.ts:487:15)
at async fn (/app/node_modules/ai/core/generate-text/stream-text.ts:991:9)
at async /app/node_modules/ai/core/telemetry/record-span.ts:18:22 {
cause: undefined,
url: XXXXX
....Minimal Reproduction Code
import { streamText, StreamTextResult } from 'ai';
import { createOpenAI } from '@ai-sdk/openai';
async function chatWithAPI(): Promise<StreamTextResult> {
try {
const apiProvider = createOpenAI({
name: 'custom-api',
apiKey: 'dummy-key',
baseURL: 'http://api.example.com/v1', // Intentionally wrong URL to trigger 404
});
const result = streamText({
model: apiProvider('model-id'),
messages: [
{
role: 'user',
content: 'Hello'
}
],
onFinish: async ({ text }) => {
console.log('Finished:', text);
},
async onChunk(chunk) {
if ('error' in chunk) {
console.error('Chunk error:', chunk.error);
throw new Error(API Error: ${ chunk.error });
}
},
maxRetries: 2
});
return result;
} catch (error) {
console.error('Error caught:', error);
throw new Error('Failed to process request');
}
}Environment
- ai version: 4.0.18
- @ai-sdk/openai version : 1.0.8
- Node.js version: 18.x
AI provider
@ai-sdk/openai version : 1.0.8
Additional context
This issue was supposedly fixed in #3987, but the problem persists in the latest version (4.0.18). The error handling mechanisms (try/catch blocks) are not catching the errors from the streaming process, causing the application to crash unexpectedly.
Expected Behavior
Errors should be properly caught either:
- In the try/catch block
- Or propagated as a proper error response through the stream
Would appreciate guidance on whether this is a known limitation or if there's a workaround available.
Activity
lgrammel commentedon Dec 16, 2024
The error will happen after the function in your example has returned the stream text result, and the return type is only a
Promisebc your method is async (it does not need to be in your example).Therefore your
tryblock can never catch it. The error happens during the consumption of the stream, not during the creation of the stream text result.I would need to know more about how you use the result / consume the stream.
samihamine commentedon Dec 17, 2024
Thanks @lgrammel for pointing out that the issue occurs after the function has returned the stream text result. This clarification helped me resolve the problem. I truly appreciate your quick response and detailed explanation – it was incredibly helpful.
Thanks again for your support!
kachar commentedon Dec 20, 2024
This was useful:
Straight out of the docs: https://sdk.vercel.ai/docs/ai-sdk-core/error-handling#handling-streaming-errors-streaming-with-error-support
Pascaltib commentedon Jan 23, 2025
I don't really understand the streaming process but how would this work when you return the stream as a response with
toDataStreamResponse()?In this example, how can I capture any errors?
If I add the example in the documentation it will work and will log the error but the text will no longer be streamed.
lgrammel commentedon Feb 6, 2025
I have introduced an
onErrorcallback onstreamText: #4729 ([email protected])streamTextimmediately starts streaming to enable sending data without waiting for the model.Errors become part of the stream and are not thrown to prevent e.g. servers from crashing.
To log errors, you can provide an
onErrorcallback that is triggered when an error occurs.Pascaltib commentedon Feb 6, 2025
Ahh thanks Igrammel!
That's amazing I will be using that for sure :)
Thanks for the help
polly3d commentedon Mar 1, 2025
That's save my day. Thanks so much!
lucasbaze commentedon Mar 12, 2025
Ran into the same issue. The newest update [email protected] solves this.
rob-gordon commentedon Mar 22, 2025
Even with the
onErrorcallback I was still struggling to get the error message to the client side because I had already returnedresult.toDataStreamResponse()from my route.I was only getting the cryptic
"An error occured"response in the stream. For anyone else struggling with this I was able to solve it withtoDataStreamResponse'sgetErrorMessageproperty.lgrammel commentedon Mar 24, 2025
@rob-gordon the error that you received in
onErrorandgetErrorMessageshould be the same error. If you only want to forward the error message to the client, you do not needonError, you can just extract the error msg ingetErrorMessage, see also https://sdk.vercel.ai/docs/ai-sdk-ui/chatbot#error-messageshendychua commentedon Apr 7, 2025
Thanks @lgrammel for your replies on this thread, which have been helpful for me.
I am implementing fallbacks with
streamText. Basically I have an array of models to try and I am iterating through the models withstreamTextbeing a call in each iteration. I followed the suggestion here - #4099 (comment) - to catch the errors synchronously (and if any errors are present move to the next iteration).I’m also using dataStreamWriter to merge the resp from
streamText.The issue I’m facing now is that even though the error from the first model is caught and the fallback model is being used, the error is still being streamed back to the client immediately. (I’m using
useChaton the client.) the client receives an error part (https://sdk.vercel.ai/docs/ai-sdk-ui/stream-protocol#error-part) and displays an error message despite valid data being streamed back after that.Do you have any suggestions on how to work around this or if I’m doing something incorrectly?
Thank you!
lgrammel commentedon Jul 22, 2026
Identify issue type
Identified as Feature
Confidence: High
Rationale
The reported behavior was clarified as expected streaming semantics rather than a defect. The resulting product change was an API/ergonomics enhancement for observing streaming errors, making this a feature.
Evidence
streamTextreturns and must be handled while consuming the stream, so the shown synchronoustry/catchcannot catch them.streamText.onErrorcallback in[email protected]via PR feat (ai/core): add onError callback to streamText #4729.