{"id":"935607010faa81ec","repo":"colinhacks/zod","slug":"async-refinement-encountered-during-synchronous-pa","errorCode":null,"errorMessage":"Async refinement encountered during synchronous parse operation. Use .parseAsync instead.","messagePattern":"Async refinement encountered during synchronous parse operation\\. Use \\.parseAsync instead\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/zod/src/v3/types.ts","lineNumber":4380,"sourceCode":"        const result = this._def.schema._parseSync({\n          data: processed,\n          path: ctx.path,\n          parent: ctx,\n        });\n        if (result.status === \"aborted\") return INVALID;\n        if (result.status === \"dirty\") return DIRTY(result.value);\n        if (status.value === \"dirty\") return DIRTY(result.value);\n        return result;\n      }\n    }\n    if (effect.type === \"refinement\") {\n      const executeRefinement = (acc: unknown): any => {\n        const result = effect.refinement(acc, checkCtx);\n        if (ctx.common.async) {\n          return Promise.resolve(result);\n        }\n        if (result instanceof Promise) {\n          throw new Error(\"Async refinement encountered during synchronous parse operation. Use .parseAsync instead.\");\n        }\n        return acc;\n      };\n\n      if (ctx.common.async === false) {\n        const inner = this._def.schema._parseSync({\n          data: ctx.data,\n          path: ctx.path,\n          parent: ctx,\n        });\n        if (inner.status === \"aborted\") return INVALID;\n        if (inner.status === \"dirty\") status.dirty();\n\n        // return value is ignored\n        executeRefinement(inner.value);\n        return { status: status.value, value: inner.value };\n      } else {\n        return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((inner) => {","sourceCodeStart":4362,"sourceCodeEnd":4398,"githubUrl":"https://github.com/colinhacks/zod/blob/912f0f51b0ced654d0069741e7160834dca742ee/packages/zod/src/v3/types.ts#L4362-L4398","documentation":"Thrown inside ZodEffects when an effect of type 'refinement' returns a Promise during a synchronous parse (ctx.common.async === false). Refinements must be sync for sync parse; this guard prevents the parse from silently discarding an unawaited async check.","triggerScenarios":"Defining `.refine(async (val) => ...)` and then calling `.parse()` or `.safeParse()` (not the Async variants). Also triggered when a sync schema embeds an async-refined subschema.","commonSituations":"Adding an async side-effecting validation (DB lookup, HTTP check) to a schema used in a sync request handler; tests calling `.parse` on an async schema; refactors that turn a sync check async.","solutions":["Call `.parseAsync(data)` / `.spa(data)` instead of `.parse` / `.safeParse`.","If you cannot go async, make the refinement synchronous (e.g. cache the lookup, or move the check out of the schema).","Move the async refinement into a separate code path so the sync schema stays sync."],"exampleFix":"// before\nconst schema = z.object({ email: z.string() }).refine(\n  async (v) => await isUnique(v.email)\n);\nschema.parse(input); // throws\n\n// after\nawait schema.parseAsync(input);","handlingStrategy":"retry","validationCode":"function isRefinementAsync(fn: Function) {\n  // best-effort: parse a probe and detect a returned Promise\n  const r = fn(undefined as any, undefined as any);\n  return r instanceof Promise;\n}","typeGuard":null,"tryCatchPattern":"try { schema.parse(data); }\ncatch (e) {\n  if (e instanceof Error && /Async refinement|Use \\.parseAsync/.test(e.message)) {\n    return await schema.parseAsync(data);\n  }\n  throw e;\n}","preventionTips":["Treat any refinement using `async` as forcing parseAsync everywhere the schema is used.","Keep side-effecting (DB/HTTP) checks out of schemas used in sync paths.","Annotate async-only schemas with a JSDoc note."],"tags":["refinement","async","effects","v3"],"analyzedSha":"912f0f51b0ced654d0069741e7160834dca742ee","analyzedAt":"2026-08-03T17:41:55.908Z","schemaVersion":2}