mastra-ai/mastra · error · Error
Dynamic workflow "${def.id}" failed validation with ${issues
Error message
Dynamic workflow "${def.id}" failed validation with ${issues.length} issue(s):
${details} What it means
When a dynamically created workflow definition is registered via addDynamicWorkflows, Mastra validates it with validateDynamicWorkflow. If any issues are found, assertValidDynamicWorkflow throws this aggregated Error listing each issue code, path, and message. It is a save-time guard so invalid workflow definitions never enter the registry.
Source
Thrown at packages/core/src/workflows/dynamic/validate/index.ts:66
index,
[
...validateWorkflowStructure(def),
...validateWorkflowSchemas(def),
...validateWorkflowRefs(def, index),
...inference.issues,
],
inference.stepOutputs,
inference.entryInputs,
inference.finalOutput,
);
}
/** Throwing presentation of {@link validateDynamicWorkflow} for the save path. */
export function assertValidDynamicWorkflow(def: WorkflowValidationInput, index: WorkflowRegistryIndex = {}): void {
const issues = validateDynamicWorkflow(def, index);
if (issues.length === 0) return;
const details = issues.map(issue => `- [${issue.code}] ${issue.path}: ${issue.message}`).join('\n');
throw new Error(`Dynamic workflow "${def.id}" failed validation with ${issues.length} issue(s):\n${details}`);
}
View on GitHub (pinned to 75dd419e61)
Solutions
- Read the issue list in the error message; fix each [code] at the given path in the workflow definition.
- Ensure every step referenced by edges/conditions actually exists in the definition and has a unique id.
- Check variable bindings (paths, kinds, step ids) match the declared step schemas.
- If the workflow references agents/tools by id, register them on the Mastra instance or pass instances directly before saving.
- Re-run validation client-side with validateDynamicWorkflow (non-throwing) before calling addDynamicWorkflows to get structured issues.
Example fix
// before
await mastra.addDynamicWorkflows({ id: 'wf', steps: { a: {...} }, edges: [{ from: 'a', to: 'missingStep' }] });
// after
const issues = validateDynamicWorkflow(def);
if (issues.length) console.error(issues); // fix dangling edges first
await mastra.addDynamicWorkflows({ id: 'wf', steps: { a: {...} }, edges: [{ from: 'a', to: 'b' }], ... }); Defensive patterns
Strategy: validation
Validate before calling
import { validateDynamicWorkflow } from './workflows/dynamic/validate';
const issues = validateDynamicWorkflow(def, {});
if (issues.length > 0) {
throw new Error('Invalid workflow: ' + issues.map(i => `[${i.code}] ${i.path}: ${i.message}`).join('; '));
}
await mastra.addDynamicWorkflows(def); Try / catch
try { await mastra.addDynamicWorkflows(def); } catch (e) { if (e.message.includes('failed validation')) { logIssues(parseIssues(e.message)); } else throw e; } Prevention
- Validate definitions with validateDynamicWorkflow before saving.
- Keep a canonical generator function for dynamic workflows rather than hand-built objects.
- Add unit tests that validate every shipped dynamic workflow definition.
- Lint for dangling edge targets and duplicate step ids in workflow JSON.
When it happens
Trigger: Calling mastra.addDynamicWorkflows(...) (or the corresponding server/API route) with a definition whose steps, edges, variables, or references fail structural validation — e.g. missing step ids, dangling edges, invalid variable paths, duplicate ids, or references to non-registered agents/tools.
Common situations: Programmatic workflow generation (LLM-authored or codegen'd workflows) producing slightly invalid graphs; hand-edited dynamic workflow JSON; renaming steps without updating edges or variable bindings; submitting workflows through the dynamic-workflow API endpoint.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Invalid cron expression: expected a non-empty cron string (e
- Invalid cron expression "${cron}": ${reason}
- perPage must be a positive integer
- page must be a non-negative integer
- ClaudeSDKAgent resumeData must include sessionId or continue
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/c854891f937491be.
Report an issue: GitHub.