z.compile: an async callback under z.lazy() throws a TypeError instead of $ZodAsyncError
Author: colinhacksCreated Sep 9, 2026Updated Sep 13, 2026
A compiled schema whose z.lazy() wraps an async callback throws a TypeError from the generated code. The interpreter throws $ZodAsyncError, which tells the caller to use parseAsync.
import * as z from "zod";
const schema = z.lazy(() => z.string().transform(async (v) => v));
schema.safeParse("a");
// $ZodAsyncError: Encountered Promise during synchronous parse. Use .parseAsync() instead.
z.compile(schema).safeParse("a");
// TypeError: Cannot read properties of undefined (reading 'length')Same with .refine(async ...) under z.lazy(), and z.validate() on the compiled schema throws the same TypeError. A compiled z.string().transform(async ...) without the lazy wrapper throws $ZodAsyncError like the interpreter does, so this is the lazy path specifically. The generated validator crashes before it reaches the fallback that would have raised the right error.
Reproduced on current main under --conditions=@zod/source.
Source: colinhacks/zod