mastra-ai/mastra · warning · HTTPException
runId required to stream workflow
Error message
runId required to stream workflow
What it means
A 400 request-validation error thrown by the workflow stream handler when the `runId` parameter is missing. After workflowId is validated, the handler rejects streaming requests without a runId because the stream is attached to an existing run created via createRun (or starts one only when a runId can be resolved).
Source
Thrown at packages/server/src/server/handlers/workflows.ts:572
responseType: 'stream',
pathParamSchema: workflowIdPathParams,
queryParamSchema: runIdSchema,
bodySchema: streamWorkflowBodySchema,
summary: 'Stream workflow execution',
description: 'Executes a workflow and streams the results in real-time',
tags: ['Workflows'],
requiresAuth: true,
handler: async ({ mastra, workflowId, runId, resourceId, requestContext, ...params }) => {
try {
// Use effective resourceId (context key takes precedence over client-provided value)
const effectiveResourceId = getEffectiveResourceId(requestContext, resourceId);
if (!workflowId) {
throw new HTTPException(400, { message: 'Workflow ID is required' });
}
if (!runId) {
throw new HTTPException(400, { message: 'runId required to stream workflow' });
}
const { workflow } = await listWorkflowsFromSystem({ mastra, workflowId });
if (!workflow) {
throw new HTTPException(404, { message: 'Workflow not found' });
}
const existingRun = await workflow.getWorkflowRunById(runId, { withNestedWorkflows: false });
if (existingRun && TERMINAL_RUN_STATUSES.includes(existingRun.status)) {
throw new HTTPException(409, {
message:
`Workflow run ${runId} already finished with status "${existingRun.status}". ` +
`Use /observe to read its stream back, or stream a new runId.`,
});
}
View on GitHub (pinned to 75dd419e61)
Solutions
- Always call createRun() first and pass its runId to the stream call.
- Await createRun before opening the stream to avoid the undefined-runId race.
- Check your @mastra/client-js version's stream() signature — pass runId via the expected parameter (body field or path).
- Add a falsy guard on runId before dispatching the stream request.
Example fix
// before
const runPromise = wf.createRun({});
const stream = await wf.stream({ runId: runPromise.runId }); // not awaited -> undefined
// after
const { runId } = await wf.createRun({});
const stream = await wf.stream({ runId }); Defensive patterns
Strategy: validation
Validate before calling
export async function streamWithRun(client: MastraClient, workflowId: string, runId?: string) {
const id = runId ?? (await client.getWorkflow(workflowId).createRun({})).runId;
if (!id) throw new Error('runId required to stream workflow');
return client.getWorkflow(workflowId).stream({ runId: id });
} Type guard
function hasRunHandle(r: { runId?: string } | undefined): r is { runId: string } {
return typeof r?.runId === 'string' && r.runId.length > 0;
} Try / catch
try {
const stream = await wf.stream({ runId });
} catch (e) {
if (e instanceof MastraClientError && e.status === 400 && /runid/i.test(e.message)) {
const { runId: fresh } = await wf.createRun({});
return wf.stream({ runId: fresh });
}
throw e;
} Prevention
- Always await createRun() before streaming — never pass an unresolved promise's property.
- Auto-create a run in your stream helper when runId is absent.
- Check the client-js stream() signature for your version to confirm how runId is passed.
When it happens
Trigger: POST /api/workflows/{workflowId}/stream without runId in path/body, calling `workflow.stream()` without first obtaining a runId, or a race where the stream call fires before createRun resolves.
Common situations: UI starts streaming before createRun's promise resolves (runId still null); custom transport drops the runId body field; SDK version mismatch where stream() no longer auto-creates runs.
Understand the failure class
Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.
Related errors
- runId required to resume workflow
- runId required to start run
- runId required to time travel workflow stream
- runId required to cancel workflow run
- Path is required
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/2f89903d416140b3.
Report an issue: GitHub.