fromZodIssue

Converts a single Zod issue into a ValidationError.

Signature

function fromZodIssue(
  issue: ZodIssue,
  options?: FromZodIssueOptions
): ValidationError

Description

While a ZodError represents an entire collection of validation failures (the whole form failed), a ZodIssue represents exactly one distinct validation failure (e.g., this specific email field failed regex).

fromZodIssue takes that single issue and applies zod-validation-error's powerful string formatting algorithms to it, outputting a standard ValidationError.

When to use this?

You almost exclusively use fromZodIssue when you are writing a Custom Zod Error Map. Error Maps process validation failures one issue at a time. If you want to override the wording of one specific error code, but want to rely on zod-validation-error to beautifully format all the other error codes, fromZodIssue is the tool for the job.

Arguments

  • issue (ZodIssue): A single Zod issue instance.
  • options (FromZodIssueOptions, optional): Formatting options. This interface is identical to MessageBuilderOptions, except it excludes maxIssuesInMessage (because it's logically impossible to have multiple issues when passing a single issue object).

Example: Selective Custom Error Map

Imagine you want to provide a highly custom message only when the error is an invalid_type, but you want standard, human-readable formatting for everything else (like too small, too big, invalid regex, etc.).

import { z as zod } from 'zod';
import { fromZodIssue } from 'zod-validation-error';

const customErrorMap: zod.ZodErrorMap = (issue, ctx) => {

  // 1. Intercept a specific error code
  if (issue.code === 'invalid_type') {
    return { message: `Hey! You gave us a ${typeof issue.received}, but we really needed a ${issue.expected}.` };
  }

  // 2. For all other error codes, fall back to zod-validation-error's formatting.
  // We construct a ValidationError and extract its message.
  const validationError = fromZodIssue({
    ...issue,
    // Provide a fallback message if the issue doesn't have one
    message: issue.message ?? ctx.defaultError,
  }, {
    // You can pass options here too!
    includePath: true, 
    forceTitleCase: true
  });

  return { message: validationError.message };
};

// Apply it globally
zod.setErrorMap(customErrorMap);