Boundary validation
Validate request bodies, configuration, or other external data while returning structured errors to the caller.
Zod · Module
.safeParse validates input and returns a result object instead of throwing on validation failure. Check success to access either parsed data or a ZodError.
Call .safeParse on a schema with unknown input when validation failure should be handled as data rather than thrown as an exception. The returned discriminated union has success: true with parsed data, or success: false with a ZodError in error.
schema.safeParse(data)| Name | Type | Description |
|---|---|---|
data | unknown | The unknown value to validate against the schema. |
A discriminated union: { success: true; data: T } on success or { success: false; error: ZodError } on failure.
.safeParse() provides a plain result object, avoiding exception handling with try/catch for validation failures.success discriminant separates successful parsing from failure and enables straightforward type-safe branching.ZodError through its error property.data property..safeParseAsync() when the schema contains asynchronous refinements or transforms; synchronous .safeParse() is not the appropriate method.import { z } from "zod";
const Player = z.object({
username: z.string(),
xp: z.number(),
});
const result = Player.safeParse({ username: "billie", xp: 100 });
if (result.success) {
console.log(result.data.username);
} else {
console.error(result.error);
}The discriminant lets the branches access validated data or the validation error safely.
Validate request bodies, configuration, or other external data while returning structured errors to the caller.
Handle user-provided values where invalid input is an expected branch rather than an exceptional condition.
Use the result discriminant to safely narrow between validated output and detailed validation errors.
safeParse return?safeParse validates input without requiring a try/catch for ordinary validation failures. It returns a discriminated union: successful results contain parsed data, while failed results contain a ZodError in error.
Follow-up: How should asynchronous schema logic be handled? Use safeParseAsync() and await its result when asynchronous refinements or transforms are involved.
safeParse result?The result is discriminated by the boolean success property. After checking if (!result.success), TypeScript can expose result.error; in the other branch, result.data is available.
Follow-up: Why is this preferable to inspecting whether data or error exists? The explicit discriminant gives reliable type narrowing and represents the two mutually exclusive outcomes.
safeParse be used instead of parse?Use safeParse when invalid input is an expected outcome that should be represented as a result object instead of an exception. This is useful at boundaries where callers can respond directly to validation errors.
Follow-up: What alternative applies when only acceptance or rejection matters? The current documentation points to .validate() or top-level z.validate(schema, data) for that narrower need.
parsesafeParseAsyncZodErrorvalidatez.validate