{"id":"fef3ed001efd6eb4","repo":"colinhacks/zod","slug":"asynchronous-transform-encountered-during-synchron","errorCode":null,"errorMessage":"Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.","messagePattern":"Asynchronous transform encountered during synchronous parse operation\\. Use \\.parseAsync instead\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/zod/src/v3/types.ts","lineNumber":4421,"sourceCode":"            return { status: status.value, value: inner.value };\n          });\n        });\n      }\n    }\n\n    if (effect.type === \"transform\") {\n      if (ctx.common.async === false) {\n        const base = this._def.schema._parseSync({\n          data: ctx.data,\n          path: ctx.path,\n          parent: ctx,\n        });\n\n        if (!isValid(base)) return INVALID;\n\n        const result = effect.transform(base.value, checkCtx);\n        if (result instanceof Promise) {\n          throw new Error(\n            `Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`\n          );\n        }\n\n        return { status: status.value, value: result };\n      } else {\n        return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((base) => {\n          if (!isValid(base)) return INVALID;\n\n          return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({\n            status: status.value,\n            value: result,\n          }));\n        });\n      }\n    }\n\n    util.assertNever(effect);","sourceCodeStart":4403,"sourceCodeEnd":4439,"githubUrl":"https://github.com/colinhacks/zod/blob/912f0f51b0ced654d0069741e7160834dca742ee/packages/zod/src/v3/types.ts#L4403-L4439","documentation":"Thrown inside ZodEffects when an effect of type 'transform' returns a Promise during a synchronous parse. Transforms that resolve asynchronously cannot be applied synchronously, so zod refuses rather than producing a Promise-typed output in a sync slot.","triggerScenarios":"Using `.transform(async (val) => ...)` (or a transform that incidentally returns a thenable) and invoking `.parse()` / `.safeParse()`. Nested transforms inside an object/array can trigger it too.","commonSituations":"Converting a transform that fetches related data into async; using `.transform(async ...)` with `.refine` chaining in a sync handler; tests calling the sync API.","solutions":["Use `.parseAsync` / `.spa` at the call site.","Make the transform synchronous if a sync result is required (precompute, look up in-memory).","Split the schema so the async transform lives in a separate async-validated schema."],"exampleFix":"// before\nconst schema = z.string().transform(async (id) => await fetchUser(id));\nschema.parse(id); // throws\n\n// after\nconst user = await schema.parseAsync(id);","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { schema.parse(data); }\ncatch (e) {\n  if (e instanceof Error && /Asynchronous transform|Use \\.parseAsync/.test(e.message)) {\n    return await schema.parseAsync(data);\n  }\n  throw e;\n}","preventionTips":["Prefer sync transforms unless you genuinely need I/O.","If a transform is async, route every consumer through parseAsync/spa.","Add a unit test that exercises the async path to catch sync usage early."],"tags":["transform","async","effects","v3"],"analyzedSha":"912f0f51b0ced654d0069741e7160834dca742ee","analyzedAt":"2026-08-03T17:41:55.908Z","schemaVersion":2}