#6608·zod

`parseAsync()` can return the fastest successful union option instead of the first option in order

Author: AaroniusCreated Sep 16, 2026Updated Sep 16, 2026

When parsing a union asynchronously, an earlier option may return a promise while a later synchronous option succeeds immediately. In that case, parseAsync() returns the later option's result without waiting for the earlier option.

For example:

import * as z from "zod";

const schema = z.union([
  z.string().transform(async () => {
    await Promise.resolve();
    return "first";
  }),
  z.string().transform(() => "second"),
]);

console.log(await schema.parseAsync("input"));

Actual behavior: second Expected behavior: first

The documentation states:

The first value that validates successfully is returned.

I assume “first” means the first successful option in the order supplied to z.union(), rather than whichever option finishes first.

I have a fix here and am happy to open a PR for it (I don't have rights to do so).