StreamErrorRetryProcessor
StreamErrorRetryProcessor is an error processor that retries transient LLM API and stream failures. It includes built-in matching for OpenAI Responses stream errors and supports additional matchers for other provider-specific error shapes.
The processor isn't enabled by default in core. Add it to errorProcessors for agents that need bounded retry handling.
Usage exampleDirect link to Usage example
Add StreamErrorRetryProcessor to errorProcessors:
import { Agent } from '@mastra/core/agent'
import { StreamErrorRetryProcessor } from '@mastra/core/processors'
export const agent = new Agent({
id: 'openai-agent',
name: 'openai-agent',
instructions: 'You are a helpful assistant.',
model: 'openai/gpt-5',
errorProcessors: [new StreamErrorRetryProcessor()],
})
How it worksDirect link to How it works
The processor checks the error and its cause chain for:
- Provider retry metadata:
isRetryable === true - Built-in OpenAI Responses stream error matching
- Matcher results: Any configured matcher that returns
true
When the error is retryable, the processor returns { retry: true }. It doesn't mutate messages.
When delayMs is set, the processor waits before signaling a retry. This is useful for transient network errors like ECONNRESET where immediately retrying is likely to fail again. The delay can be a fixed number of milliseconds or a function evaluated with the error args (for example, to implement exponential backoff).
Retry limitsDirect link to Retry limits
maxRetries defaults to 1 and limits this processor's retry requests. The agent also limits processor retries with maxProcessorRetries. When error processors are configured without an agent limit, the runtime cap is 10.
Set both values explicitly to the same bounded value when you need a single retry budget. Keep model maxRetries at 0 for that call to avoid multiplying provider attempts.
Retry-After handlingDirect link to retry-after-handling
For retryable errors with a Retry-After response header, the processor reads case-insensitive delta-seconds and HTTP-date values through the error cause chain. It waits for the longer of delayMs and the bounded server delay.
maxRetryAfterMs defaults to 30_000. It caps only provider-provided wait time. A longer explicit delayMs remains unchanged. Invalid or expired headers are ignored.
Retry unknown errorsDirect link to Retry unknown errors
Set retryUnknownErrors to retry errors that don't match provider metadata, the built-in OpenAI matcher, or a custom matcher. Unknown-error retries use the processor-level maxRetries and delayMs values. Known authorization failures, including HTTP 401 and 403 responses, aren't retried:
import { Agent } from '@mastra/core/agent'
import { StreamErrorRetryProcessor } from '@mastra/core/processors'
export const agent = new Agent({
id: 'resilient-agent',
name: 'Resilient agent',
instructions: 'You are a helpful assistant.',
model: 'openai/gpt-5',
errorProcessors: [
new StreamErrorRetryProcessor({
retryUnknownErrors: true,
maxRetries: 2,
delayMs: 3000,
}),
],
})
Specific matcher policies still take precedence over the unknown-error values. The option defaults to false, so unknown errors aren't retried unless you enable it.
Delaying retriesDirect link to Delaying retries
Use delayMs with a custom matcher to retry transient network resets with a wait:
import { Agent } from '@mastra/core/agent'
import { StreamErrorRetryProcessor } from '@mastra/core/processors'
const isECONNRESET = (error: unknown) => {
if (!error || typeof error !== 'object') return false
const code = (error as { code?: unknown }).code
if (typeof code === 'string' && code.toUpperCase() === 'ECONNRESET') return true
const message = error instanceof Error ? error.message : undefined
return typeof message === 'string' && /econnreset|socket hang up/i.test(message)
}
export const agent = new Agent({
id: 'resilient-agent',
name: 'resilient-agent',
instructions: 'You are a helpful assistant.',
model: 'openai/gpt-5',
errorProcessors: [
new StreamErrorRetryProcessor({
maxRetries: 2,
delayMs: ({ retryCount }) => Math.min(1000 * 2 ** retryCount, 30000),
matchers: [isECONNRESET],
}),
],
})
Default OpenAI Responses matcherDirect link to Default OpenAI Responses matcher
isRetryableOpenAIResponsesStreamError matches OpenAI Responses stream error chunks with type: 'error' or type: 'response.failed'. It retries known transient OpenAI error codes and, as a fallback, errors with explicit retry guidance such as You can retry your request.
StreamErrorRetryProcessor includes this matcher by default. You can also import it and reuse it in custom retry logic.