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

  1. Inspect the union schema in the failing validator and log each option — find the `undefined` one.
  2. Fix the import (avoid circular dependencies between schema modules; import directly instead of via barrels).
  3. Guard conditional unions: filter/fallback, e.g. `z.union(opts.filter(Boolean))`, and add a dev-time assertion that every option is defined.
  4. 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

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


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