mastra-ai/mastra · error · HTTPException
runId required to start run
Error message
runId required to start run
What it means
Thrown by the start-run handler when `runId` is missing after workflowId validation. Starting a run by id requires the caller-supplied runId, so the server returns HTTP 400 before resolving the workflow.
Source
Thrown at packages/server/src/server/handlers/workflows.ts:718
responseType: 'json',
pathParamSchema: workflowIdPathParams,
queryParamSchema: runIdSchema,
bodySchema: startAsyncWorkflowBodySchema,
responseSchema: workflowControlResponseSchema,
summary: 'Start specific workflow run',
description: 'Starts execution of a specific workflow run by ID',
tags: ['Workflows'],
requiresAuth: true,
handler: async ({ mastra, workflowId, runId, requestContext, ...params }) => {
try {
const effectiveResourceId = getEffectiveResourceId(requestContext, undefined);
if (!workflowId) {
throw new HTTPException(400, { message: 'Workflow ID is required' });
}
if (!runId) {
throw new HTTPException(400, { message: 'runId required to start run' });
}
const { workflow } = await listWorkflowsFromSystem({ mastra, workflowId });
if (!workflow) {
throw new HTTPException(404, { message: 'Workflow not found' });
}
const run = await workflow.getWorkflowRunById(runId);
if (!run) {
throw new HTTPException(404, { message: 'Workflow run not found' });
}
await validateRunOwnership(run, effectiveResourceId);
const _run = await workflow.createRun({ runId, resourceId: run.resourceId });
// Fire-and-forget: attach .catch so a rejected start (e.g. invalid inputView on GitHub (pinned to 75dd419e61)
Solutions
- Pass the runId obtained from `workflow.createRun({ runId })` or your own generated id.
- Persist the runId where the starting service can read it (queue, DB, shared store).
- Trim/validate the runId input client-side before calling.
Example fix
// before
await client.startRun({ workflowId, runId: undefined })
// after
const { runId } = await workflow.createRun();
await client.startRun({ workflowId, runId }) Defensive patterns
Strategy: validation
Validate before calling
if (!runId) {
throw new TypeError('runId is required to start a run; get one from workflow.createRun()');
}
await client.startRun({ workflowId, runId }); Type guard
function hasRunId(x: { runId?: string }): x is { runId: string } {
return typeof x.runId === 'string' && x.runId.trim().length > 0;
} Try / catch
try {
await client.startRun({ workflowId, runId });
} catch (e) {
if (e instanceof MastraClientError && e.status === 400 && /runId/.test(e.message)) {
const newRun = await client.createRun(workflowId);
return client.startRun({ workflowId, runId: newRun.runId });
}
throw e;
} Prevention
- Create and start the run in the same code path so runId never crosses a serialization boundary.
- If creation and start must be split, pass runId through durable state, not memory.
- Trim user-supplied runIds and reject empty strings before calling the API.
When it happens
Trigger: Call to the start-run endpoint without runId in path/body; passing the workflowId twice instead of workflowId+runId; runId variable lost between creating the run and starting it (e.g. across processes).
Common situations: Distributed setups where one service creates the run and another starts it but forgets to pass the id; SDK misuse passing an options object as the runId; empty string from an untrimmed input field.
Related errors
- runId required to resume workflow
- runId required to stream workflow
- 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/dccaa4a841b21e81.
Report an issue: GitHub.