mastra-ai/mastra · error · Error
Workflow '${workflow.id}' (key: '${workflowKey}') must have
Error message
Workflow '${workflow.id}' (key: '${workflowKey}') must have a non-empty description to be used in an MCPServer. What it means
Workflows registered on an MCPServer become tools named `run_<workflowKey>`, and the server requires each workflow to have a non-empty `description` because MCP tool definitions need a description. This Error is thrown at server setup when a registered workflow's description is empty or undefined.
Source
Thrown at packages/mcp/src/server/server.ts:1583
definedConvertedTools?: Record<string, InternalCoreTool>,
): Record<string, InternalCoreTool> {
const workflowTools: Record<string, InternalCoreTool> = {};
if (!workflowsConfig) {
return workflowTools;
}
for (const workflowKey in workflowsConfig) {
const workflow = workflowsConfig[workflowKey];
if (!workflow || typeof workflow.createRun !== 'function') {
this.logger.warn(
`Workflow instance for '${workflowKey}' is invalid or missing a createRun function. Skipping.`,
);
continue;
}
const workflowDescription = workflow.description;
if (!workflowDescription) {
throw new Error(
`Workflow '${workflow.id}' (key: '${workflowKey}') must have a non-empty description to be used in an MCPServer.`,
);
}
const workflowToolName = `run_${workflowKey}`;
if (definedConvertedTools?.[workflowToolName] || workflowTools[workflowToolName]) {
this.logger.warn(
`Tool with name '${workflowToolName}' already exists. Workflow '${workflowKey}' will not be added as a duplicate tool.`,
);
continue;
}
const workflowToolDefinition = createTool({
id: workflowToolName,
description: `Run workflow '${workflowKey}'. Workflow description: ${workflowDescription}`,
inputSchema: workflow.inputSchema,
execute: async (inputData, context) => {
this.logger.debug(View on GitHub (pinned to 75dd419e61)
Solutions
- Pass a non-empty description when creating the Workflow: new Workflow({ id: 'myWorkflow', description: '...' })
- Remove the workflow from the MCPServer's workflows map if it should not be exposed
- Add a build-time or startup check that all MCPServer-registered workflows have descriptions
Example fix
// before
const wf = new Workflow({ id: 'etlWorkflow' });
new MCPServer({ workflows: { etlWorkflow: wf } });
// after
const wf = new Workflow({ id: 'etlWorkflow', description: 'Runs the nightly ETL pipeline over uploaded CSVs.' });
new MCPServer({ workflows: { etlWorkflow: wf } }); Defensive patterns
Strategy: validation
Validate before calling
for (const [key, workflow] of Object.entries(workflowsMap)) {
if (!workflow.description) {
throw new Error(`Workflow '${key}' has no description; add one before registering on an MCPServer.`);
}
} Type guard
function hasWorkflowDescription(workflow) {
return typeof workflow.description === 'string' && workflow.description.length > 0;
} Try / catch
try {
const server = new MCPServer({ name, version, workflows });
await server.start();
} catch (e) {
if (e instanceof Error && e.message.includes('non-empty description')) {
// parse workflow id from the message and add a description
} else throw e;
} Prevention
- Always pass a description when constructing workflows, even for internal use
- Add a startup test that all MCPServer-registered workflows have non-empty descriptions
- Use descriptions that would make sense as MCP tool descriptions for LLM consumers
When it happens
Trigger: new MCPServer({ workflows: { myWorkflow: workflow } }) where the Workflow was created without a description (new Workflow({ id, description }) omitted or set to ''), evaluated when the server builds its workflow tools.
Common situations: Workflows defined programmatically without descriptions for internal orchestration, then registered on an MCPServer; older workflow code predating the description requirement; a dynamically created workflow whose description argument was accidentally left empty.
Understand the failure class
Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.
Related errors
- Agent '${agent.name}' (key: '${agentKey}') must have a non-e
- @mastra/livekit: `workflowInput` is required when `workflow`
- save-workflow requires a Mastra context.
- InProcessStrategy: could not resolve step "${params.stepId}"
- Workflow "${params.id}" declares an array of schedules but o
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/d9075fd0aa08b817.
Report an issue: GitHub.