mastra-ai/mastra · error · HTTPException

Run ID is required

Error message

Run ID is required

What it means

Immediately after the workflowId check, the getWorkflowRunById handler validates `runId` and throws 400 'Run ID is required' when it is falsy. A workflowId alone cannot identify a run; the pair (workflowId, runId) is required to fetch the run's snapshot and execution results from storage.

Source

Thrown at packages/server/src/server/handlers/workflows.ts:437

  responseType: 'json',
  pathParamSchema: workflowRunPathParams,
  queryParamSchema: workflowRunResultQuerySchema,
  responseSchema: workflowRunResultSchema,
  summary: 'Get workflow run by ID',
  description:
    'Returns a workflow run with metadata and processed execution state. Use the fields query parameter to reduce payload size by requesting only specific fields (e.g., ?fields=status,result,metadata)',
  tags: ['Workflows'],
  requiresAuth: true,
  handler: async ({ mastra, workflowId, runId, fields, withNestedWorkflows, requestContext }) => {
    try {
      const effectiveResourceId = getEffectiveResourceId(requestContext, undefined);

      if (!workflowId) {
        throw new HTTPException(400, { message: 'Workflow ID is required' });
      }

      if (!runId) {
        throw new HTTPException(400, { message: 'Run ID is required' });
      }

      const { workflow } = await listWorkflowsFromSystem({ mastra, workflowId });

      if (!workflow) {
        throw new HTTPException(404, { message: 'Workflow not found' });
      }

      // Parse fields parameter (comma-separated string)
      const fieldList = fields ? (fields.split(',').map((f: string) => f.trim()) as WorkflowStateField[]) : undefined;

      const run = await workflow.getWorkflowRunById(runId, {
        withNestedWorkflows: withNestedWorkflows !== 'false', // Default to true unless explicitly 'false'
        fields: fieldList,
      });

      if (!run) {
        throw new HTTPException(404, { message: 'Workflow run not found' });

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Provide the runId in the request path: GET /api/workflows/:workflowId/runs/:runId
  2. Gate the detail fetch on runId being truthy in the consuming UI
  3. Persist the full (workflowId, runId) pair in links and saved state

Example fix

// before
useEffect(() => { fetchRun(workflowId, runId); }, [workflowId]);
// after
useEffect(() => { if (workflowId && runId) fetchRun(workflowId, runId); }, [workflowId, runId]);
Defensive patterns

Strategy: validation

Validate before calling

function canFetchRun(state) {
  return Boolean(state?.workflowId) && Boolean(state?.runId);
}
// usage
if (canFetchRun(state)) fetchWorkflowRun(client, state.workflowId, state.runId);

Type guard

function hasRunId(v): v is { workflowId: string; runId: string } {
  return typeof (v as any)?.runId === 'string' && (v as any).runId.length > 0;
}

Try / catch

try {
  return await getWorkflowRunById({ mastra, workflowId, runId });
} catch (e) {
  if (e?.status === 400 && /run id is required/i.test(e?.message ?? '')) {
    return { error: 'Select a run before fetching details' };
  }
  throw e;
}

Prevention

When it happens

Trigger: GET /api/workflows/:workflowId/runs/ with an empty run id; calling getWorkflowRun(undefined); a run list rendering before the selected runId state is set; route params where :runId failed to match (optional segment).

Common situations: Auto-starting detail views before a run is selected; regex route changes making runId optional; run ids lost when rehydrating UI state from storage or links shared without the run segment.

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


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