mastra-ai/mastra · error · HTTPException

Workflow run not found

Error message

Workflow run not found

What it means

This 404 is thrown when the workflow exists but `workflow.getWorkflowRunById(runId, { withNestedWorkflows, fields })` returns null/undefined because no persisted run matches the `runId`. The handler first confirms the workflow, then looks up the run from storage, and throws this if the storage lookup misses. It also fires if a nested-workflow run is requested with `withNestedWorkflows=false` (default) and the run is not directly addressable.

Source

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

        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' });
      }

      await validateRunOwnership(run, effectiveResourceId);

      return run;
    } catch (error) {
      return handleError(error, 'Error getting workflow run');
    }
  },
});

export const DELETE_WORKFLOW_RUN_BY_ID_ROUTE = createRoute({
  method: 'DELETE',
  path: '/workflows/:workflowId/runs/:runId',
  responseType: 'json',
  pathParamSchema: workflowRunPathParams,
  responseSchema: workflowControlResponseSchema,
  summary: 'Delete workflow run by ID',

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Use the exact runId returned from workflow.createRun()/the start call; never fabricate one.
  2. Confirm the runId belongs to this workflowId (runs are keyed per workflow).
  3. Check the server's storage is the same backend the run was written to; re-run against the original environment.
  4. If fetching a nested-workflow run, pass withNestedWorkflows=true (omit the param, since it defaults to true) so child runs resolve.

Example fix

// before
const res = await fetch(`/api/workflows/myWorkflow/runs/${someGeneratedId}`);
// after
const { runId } = await client.getWorkflow('myWorkflow').createRun({});
const run = await client.getWorkflowRun('myWorkflow', runId);
Defensive patterns

Strategy: try-catch

Validate before calling

if (!runId || typeof runId !== 'string') {
  throw new Error('runId must be the id returned by createRun()');
}
if (!runIdCache.has(`${workflowId}:${runId}`) && !allowMiss) return null;

Type guard

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

Try / catch

try {
  return await client.getWorkflowRun(workflowId, runId);
} catch (e) {
  if (e instanceof MastraClientError && e.status === 404) {
    return null; // run never created or already deleted
  }
  throw e;
}

Prevention

When it happens

Trigger: GET /api/workflows/{workflowId}/runs/{runId} with a runId never created, a run already deleted, a run belonging to a different workflowId, or a nested-workflow child runId fetched with withNestedWorkflows=false.

Common situations: Client constructing runIds instead of using the value returned by createRun; storage backend switched (e.g. from default in-memory to Postgres) so old run IDs are gone; run purged by retention/cleanup; typos from copying run ID across environments.

Related errors


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