mastra-ai/mastra · error · Error
Failed to stream workflow: ${response.statusText}
Error message
Failed to stream workflow: ${response.statusText} What it means
Thrown by Run.stream() when the workflow streaming POST returns a non-OK HTTP status. The library surfaces the HTTP statusText because the response is not a usable event stream. The server-side reason is not included, so check the status code/statusText for the cause.
Source
Thrown at client-sdks/client-js/src/resources/run.ts:240
searchParams.set('runId', this.runId);
const requestContext = parseClientRequestContext(params.requestContext);
const response: Response = await this.request(`/workflows/${this.workflowId}/stream?${searchParams.toString()}`, {
method: 'POST',
body: {
inputData: params.inputData,
initialState: params.initialState,
requestContext,
tracingOptions: params.tracingOptions,
resourceId: params.resourceId,
perStep: params.perStep,
closeOnSuspend: params.closeOnSuspend,
},
stream: true,
});
if (!response.ok) {
throw new Error(`Failed to stream workflow: ${response.statusText}`);
}
if (!response.body) {
throw new Error('Response body is null');
}
// Pipe the response body through the transform stream
return response.body.pipeThrough(this.createChunkTransformStream());
}
/**
* Observe (reconnect to) an existing workflow stream.
* Use this to resume receiving events after a disconnection.
*
* @param params.offset - Optional position to resume from (0-based). If omitted, replays all events.
* @returns Promise containing a ReadableStream of workflow events
*
* @exampleView on GitHub (pinned to 75dd419e61)
Solutions
- Log the full HTTP response status; if needed use the non-streaming request path to get the error body.
- Verify the run ID and workflow ID are valid and the run is in a streamable state.
- Check Mastra server logs for the underlying 4xx/5xx cause.
- Retry transient 5xx failures with backoff.
Example fix
// before
const stream = await run.stream({ inputData });
// after
try {
const stream = await run.stream({ inputData });
} catch (e) {
console.error('Workflow stream failed:', e.message); // includes statusText
} Defensive patterns
Strategy: try-catch
Validate before calling
const status = await run.status();
if (['success', 'failed'].includes(status.status)) throw new Error(`Run ${runId} not streamable (${status.status})`); Type guard
function isStreamable(status: { status: string }): boolean {
return ['pending', 'running', 'waiting', 'suspended'].includes(status.status);
} Try / catch
try {
const stream = await run.stream({ inputData });
} catch (e) {
if (/Failed to stream workflow/.test(e.message)) {
console.error('Stream rejected:', e.message);
// check server logs / fall back to run.start()
} else throw e;
} Prevention
- Check run state before streaming
- Keep run IDs fresh across server restarts
- Log statusText and correlate with server logs
- Retry 5xx with backoff
When it happens
Trigger: Calling run.stream() with params like closeOnSuspend where the server responds 4xx/5xx — e.g. unknown run ID, run already completed, or server error (client-sdks/client-js/src/resources/run.ts:240).
Common situations: Resuming a stale run ID after server restart; concurrent runs conflicting; server returning 500 due to workflow definition errors.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- Response body is null
- Failed to observe workflow stream: ${response.statusText}
- Failed to stream vNext workflow: ${response.statusText}
- Failed to time travel workflow: ${response.statusText}
- Failed to stream background tasks: ${response.statusText}
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/4c9de7732acd20c8.
Report an issue: GitHub.