mastra-ai/mastra · error
Cannot create workflow definition "${input.id}": inputSchema
Error message
Cannot create workflow definition "${input.id}": inputSchema, outputSchema, and graph are required. What it means
`upsert` in the workflow-definitions storage requires a definition record to carry non-undefined `inputSchema`, `outputSchema`, and `graph` fields. If any is missing or explicitly undefined, it refuses to persist the definition, since these three fields define the workflow contract and executable structure.
Source
Thrown at packages/core/src/storage/domains/workflow-definitions/inmemory.ts:56
...('status' in input && input.status !== undefined && { status: input.status }),
...('authorId' in input && input.authorId !== undefined && { authorId: input.authorId }),
updatedAt: now,
};
this.db.workflowDefinitions.set(input.id, merged);
return this.deepCopy(merged);
}
// Creation requires the full schema set + graph. Check values, not key
// presence — `{ graph: undefined }` must not slip through.
if (
!('inputSchema' in input) ||
input.inputSchema === undefined ||
!('outputSchema' in input) ||
input.outputSchema === undefined ||
!('graph' in input) ||
input.graph === undefined
) {
throw new Error(
`Cannot create workflow definition "${input.id}": inputSchema, outputSchema, and graph are required.`,
);
}
const def: WorkflowDefinition = {
id: input.id,
description: input.description,
metadata: input.metadata,
inputSchema: input.inputSchema,
outputSchema: input.outputSchema,
stateSchema: input.stateSchema,
requestContextSchema: input.requestContextSchema,
graph: input.graph,
status: 'active',
source: 'storage',
authorId: 'authorId' in input ? input.authorId : undefined,
createdAt: now,
updatedAt: now,View on GitHub (pinned to 75dd419e61)
Solutions
- Provide all three fields: derive `inputSchema`/`outputSchema` from the workflow (e.g. zod `.jsonSchema()` or zod-to-json-schema) and `graph` from the serialized workflow graph.
- If updating an existing definition, load it first and merge the existing schemas/graph instead of upserting a partial record.
- Validate the input payload shape before calling upsert.
- Fix serialization so `undefined` fields are not stripped or turned into explicit undefined values.
Example fix
// before
await wfStorage.upsert({ id: 'wf-1', name: 'My flow' });
// after
await wfStorage.upsert({
id: 'wf-1',
name: 'My flow',
inputSchema: z.object({}).jsonSchema(),
outputSchema: z.object({}).jsonSchema(),
graph: serializedGraph,
}); Defensive patterns
Strategy: validation
Validate before calling
function assertWorkflowDefinitionInput(input: { id: string; inputSchema?: unknown; outputSchema?: unknown; graph?: unknown }) {
const missing: string[] = [];
if (input.inputSchema === undefined) missing.push('inputSchema');
if (input.outputSchema === undefined) missing.push('outputSchema');
if (input.graph === undefined) missing.push('graph');
if (missing.length) throw new Error(`Workflow definition "${input.id}" missing: ${missing.join(', ')}`);
} Type guard
function isCompleteWorkflowDefinition(
input: Partial<{ inputSchema: unknown; outputSchema: unknown; graph: unknown }>,
): input is { inputSchema: unknown; outputSchema: unknown; graph: unknown } {
return 'inputSchema' in input && input.inputSchema !== undefined
&& 'outputSchema' in input && input.outputSchema !== undefined
&& 'graph' in input && input.graph !== undefined;
} Try / catch
try {
await wfStorage.upsert(input);
} catch (err) {
if (err instanceof Error && err.message.includes('inputSchema, outputSchema, and graph are required')) {
const existing = await wfStorage.getDefinition(input.id); // merge missing fields
await wfStorage.upsert({ ...existing, ...input });
} else throw err;
} Prevention
- Always build definitions from a complete workflow object (schemas via zodToJsonSchema, graph from the workflow).
- For updates, load the existing definition and spread it under the patch.
- Validate payloads with a schema before persistence.
When it happens
Trigger: Calling `upsert({ id, name, description })` (or via `updated`) with a partial input lacking `inputSchema`/`outputSchema`/`graph`, or spreading an object where those keys are present but set to undefined.
Common situations: Persisting a minimal/partial workflow record to 'reserve' an ID, migrating older records whose schema predates the required fields, or deserialization dropping optional-looking fields before upsert.
Understand the failure class
Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.
Related errors
- error.message (workflow schema validation error)
- Google token response did not include an ID token
- Workflow ${workflowId} not found
- Workflow ID is required
- Failed to stream workflow: ${response.statusText}
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/09ead0b86a27ff1a.
Report an issue: GitHub.