mastra-ai/mastra · error
Your schema is async, which is not supported. Please use a s
Error message
Your schema is async, which is not supported. Please use a sync schema.
What it means
`safeValidate` runs tool input/output/suspend-data validation through the Standard Schema interface and requires a synchronous result. If `schema['~standard'].validate(data)` returns a Promise, the schema performs async validation, which Mastra's tool validation path does not support, so it throws this error to fail fast with a clear message.
Source
Thrown at packages/core/src/tools/validation.ts:22
import type { PublicSchema, StandardSchemaWithJSON, StandardSchemaIssue } from '../schema';
import { getZodTypeName, isZodArray, isZodObject, unwrapZodType } from '../utils/zod-utils';
/**
* Safely validates data against a Standard Schema.
* Catches internal Zod errors (like undefined union options) and provides better error messages.
*
* @param schema The Standard Schema to validate against
* @param data The data to validate
* @returns The validation result or throws with a descriptive error
*/
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;
}View on GitHub (pinned to 75dd419e61)
Solutions
- Make the schema fully synchronous — remove async refinements/transforms from tool input/output schemas.
- Perform async checks inside the tool's `execute` after sync shape validation passes.
- If using `retryValidation`/coercion paths, confirm the fallback schema is also sync.
Example fix
// before
inputSchema: z.object({ id: z.string().refine(async id => !!(await db.find(id))) })
// after
inputSchema: z.object({ id: z.string() })
// then in execute: const row = await db.find(context.id); if (!row) throw new Error(...) Defensive patterns
Strategy: validation
Validate before calling
function assertSyncToolSchema(schema: unknown) {
const res = (schema as any)?.['~standard']?.validate({});
if (res instanceof Promise) throw new Error('Tool input/output schema must be synchronous');
} Type guard
function isSyncStandardSchema(v: unknown): v is { '~standard': { validate: (v: unknown) => { value?: unknown; issues?: readonly unknown[] } } } {
try { return !((v as any)?.['~standard']?.validate({}) instanceof Promise); } catch { return false; }
} Try / catch
try {
await tool.execute({ context: args });
} catch (e) {
if (e instanceof Error && e.message.includes('async, which is not supported')) {
console.error('Tool schema contains async validation; refactor to sync.');
}
throw e;
} Prevention
- Audit tool schemas for `refine(async`, `superRefine(async`, and async `.transform()` during code review.
- Run an early unit test that validates the schema synchronously and fails on Promise results.
- Centralize async checks in a shared execute helper instead of embedding them in schemas.
When it happens
Trigger: Providing a tool `inputSchema`/`outputSchema`/suspend data schema with async refinements (`refine(async ...)`, `superRefine(async ...)`, async `.transform()`), so tool argument validation via `validation`/`coercedValidation`/`retryValidation` hits the Promise branch.
Common situations: Async uniqueness/DB checks in tool input schemas; schemas shared from HTTP handlers using async parsers; Zod 4 pipelines with async transforms copied from server code.
Related errors
- Your schema is async, which is not supported. Please use a s
- ${label} contains an unsupported field.
- Factory rules.tools must be an object.
- Factory rules.tools.${toolName} must be an object.
- Factory rules.tools.${toolName}.onResult must be a function.
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/3935ee344cecbacf.
Report an issue: GitHub.