mastra-ai/mastra · error · Error

Failed to stream vNext workflow: ${response.statusText}

Error message

Failed to stream vNext workflow: ${response.statusText}

What it means

Thrown by Run.resumeStream() when the vNext workflow resume-stream POST returns a non-OK HTTP status. The resume request was rejected by the server, so no event stream can be established.

Source

Thrown at client-sdks/client-js/src/resources/run.ts:398

    const requestContext = parseClientRequestContext(params.requestContext);
    const response: Response = await this.request(
      `/workflows/${this.workflowId}/resume-stream?${searchParams.toString()}`,
      {
        method: 'POST',
        body: {
          step: params.step,
          resumeData: params.resumeData,
          requestContext,
          tracingOptions: params.tracingOptions,
          perStep: params.perStep,
          forEachIndex: params.forEachIndex,
        },
        stream: true,
      },
    );

    if (!response.ok) {
      throw new Error(`Failed to stream vNext 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());
  }

  /**
   * Restarts an active workflow run synchronously without waiting for the workflow to complete
   * @param params - Object containing the requestContext
   * @returns Promise containing success message
   */
  restart(params: {
    requestContext?: RequestContext | Record<string, any>;
    tracingOptions?: TracingOptions;

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Check run.status() before resuming — only suspended runs can be resumed via stream.
  2. Validate the runId/workflowId and resume data schema match the workflow's suspend/resume contract.
  3. Inspect server logs for the HTTP error detail.
  4. Guard against double-resume with application-level state.

Example fix

// before
await run.resumeStream({ resumeData: { approved: true } });

// after
const status = await run.status();
if (status.status === 'suspended') {
  await run.resumeStream({ resumeData: { approved: true } });
}
Defensive patterns

Strategy: validation

Validate before calling

const status = await run.status();
if (status.status !== 'suspended') throw new Error(`Cannot resumeStream: run is ${status.status}, expected suspended`);

Type guard

function canResume(s: { status: string }): s is { status: 'suspended' } { return s.status === 'suspended'; }

Try / catch

try {
  await run.resumeStream({ resumeData });
} catch (e) {
  if (/Failed to stream vNext workflow/.test(e.message)) {
    console.error('Resume rejected:', e.message);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling resumeStream() with a resume payload on a run that is not suspended, already finished, or with an invalid run/workflow ID; server-side errors during resume (client-sdks/client-js/src/resources/run.ts:398).

Common situations: Resuming after the suspend point no longer exists; double-resume attempts; stale run references after server redeploy.

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


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/a9abe135fbde5ac0. Report an issue: GitHub.