mastra-ai/mastra · error
Schema validation failed due to an invalid schema definition
Error message
Schema validation failed due to an invalid schema definition. This often happens when a union schema (z.union or z.or) has undefined options. Please check that all schema options are properly defined. Original error: ${err.message} What it means
When schema validation throws internally (rather than returning issues), Mastra detects the common Zod crash `Cannot read properties of undefined (reading 'run')` and rethrows this explanatory error. This crash almost always means a union schema (`z.union([...])` or `.or()`) contains an `undefined` option — typically from an import/circular-dependency problem where a schema constant is `undefined` at validation time.
Source
Thrown at packages/core/src/tools/validation.ts:33
function safeValidate<T>(
schema: StandardSchemaWithJSON<T>,
data: unknown,
): { value: T } | { issues: readonly StandardSchemaIssue[] } {
try {
const result = schema['~standard'].validate(data);
if (result instanceof Promise) {
throw new Error('Your schema is async, which is not supported. Please use a sync schema.');
}
// Prioritise issues over value: Valibot returns both on failure (typed: false).
if ('issues' in result && Array.isArray(result.issues) && result.issues.length > 0) {
return { issues: result.issues as readonly StandardSchemaIssue[] };
}
return result as { value: T } | { issues: readonly StandardSchemaIssue[] };
} catch (err) {
// Catch Zod internal errors like "Cannot read properties of undefined (reading 'run')"
// This happens when a union schema has undefined options
if (err instanceof TypeError && err.message.includes('Cannot read properties of undefined')) {
throw new Error(
`Schema validation failed due to an invalid schema definition. ` +
`This often happens when a union schema (z.union or z.or) has undefined options. ` +
`Please check that all schema options are properly defined. Original error: ${err.message}`,
);
}
throw err;
}
}
/**
* Formatted validation errors structure.
* Contains `errors` array for messages at this level, and `fields` for nested field errors.
*/
export type FormattedValidationErrors<T = unknown> = {
errors: string[];
fields: T extends object ? { [K in keyof T]?: FormattedValidationErrors<T[K]> } : unknown;
};
View on GitHub (pinned to 75dd419e61)
Solutions
- Inspect the union schema in the failing validator and log each option — find the `undefined` one.
- Fix the import (avoid circular dependencies between schema modules; import directly instead of via barrels).
- Guard conditional unions: filter/fallback, e.g. `z.union(opts.filter(Boolean))`, and add a dev-time assertion that every option is defined.
- Enable TypeScript `verbatimModuleSyntax`/strict import checks to catch undefined schema imports at build time.
Example fix
// before
import { schemaB } from './schemas'; // circular -> undefined at module init
export const input = z.union([schemaA, schemaB]);
// after
import { schemaB } from './schema-b'; // direct import breaks the cycle
export const input = z.union([schemaA, schemaB]); Defensive patterns
Strategy: validation
Validate before calling
function assertUnionOptionsDefined(...options: unknown[]) {
const bad = options.map((o, i) => [i, o]).filter(([, o]) => o === undefined);
if (bad.length) throw new Error(`Union schema options undefined at indexes: ${bad.map(([i]) => i).join(',')}`);
}
// assertUnionOptionsDefined(schemaA, schemaB) before z.union([schemaA, schemaB]) Type guard
function isDefinedSchema(v: unknown): v is NonNullable<unknown> {
return v !== undefined && v !== null && typeof v === 'object';
} Try / catch
try {
validateInput(data, schema);
} catch (e) {
if (e instanceof Error && e.message.includes('invalid schema definition')) {
console.error('Check union schema options for undefined values (likely circular/failed import).');
}
throw e;
} Prevention
- Avoid circular imports between schema modules; import schemas directly, not via barrels.
- Never build unions with conditional spreads that can emit undefined: use `.filter(Boolean)` and assert non-empty.
- Enable strict TS import checking so typos in schema imports fail at compile time.
When it happens
Trigger: A tool or workflow schema built with `z.union([schemaA, schemaB])` or `schemaA.or(schemaB)` where one operand is `undefined` at runtime (failed/hoisted import, circular dependency, conditional schema construction that skipped an option).
Common situations: Barrel-file circular imports in ESM where schema modules reference each other; conditional code like `z.union([...(useA ? [schemaA] : [])])` producing an empty/undefined entry; typos in imported schema names silently becoming undefined under TS-loose configs.
Related errors
- SchemaValidationError(field, this.formatErrors(result.error)
- We could not convert the schema to a JSONSchema
- WORKFLOW_SCHEMA_VALIDATION_FAILED
- Union must have at least 2 options
- ${label} contains an unsupported field.
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/523cf696ff45f520.
Report an issue: GitHub.