{"id":13455086,"url":"https://github.com/andrewvo89/zod-error","last_synced_at":"2025-10-27T02:17:22.873Z","repository":{"id":45727234,"uuid":"513101875","full_name":"andrewvo89/zod-error","owner":"andrewvo89","description":"Utilities to format and customize Zod error messages","archived":false,"fork":false,"pushed_at":"2023-02-22T11:37:37.000Z","size":105,"stargazers_count":50,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-11-25T04:41:53.590Z","etag":null,"topics":["error","nodejs","typescript","validation","zod"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/zod-error","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andrewvo89.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2022-07-12T10:43:10.000Z","updated_at":"2024-10-17T17:38:06.000Z","dependencies_parsed_at":"2024-01-13T17:35:35.455Z","dependency_job_id":"d947ee13-5592-44ad-86e1-4a8eaf334cb4","html_url":"https://github.com/andrewvo89/zod-error","commit_stats":{"total_commits":48,"total_committers":1,"mean_commits":48.0,"dds":0.0,"last_synced_commit":"568b678327eb72ed4f668f78b137d8b3d7eb4614"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewvo89%2Fzod-error","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewvo89%2Fzod-error/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewvo89%2Fzod-error/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewvo89%2Fzod-error/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andrewvo89","download_url":"https://codeload.github.com/andrewvo89/zod-error/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230520390,"owners_count":18238948,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["error","nodejs","typescript","validation","zod"],"created_at":"2024-07-31T08:01:01.119Z","updated_at":"2025-10-27T02:17:22.864Z","avatar_url":"https://github.com/andrewvo89.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003eZod Error\u003c/h1\u003e\r\n\r\n\u003cdiv align=\"center\"\u003e\r\n\r\n[![Status](https://img.shields.io/badge/status-active-blue)](https://github.com/andrewvo89/zod-error)\r\n[![GitHub Issues](https://img.shields.io/github/issues/andrewvo89/zod-error?color=blue)](https://github.com/andrewvo89/zod-error/issues)\r\n[![GitHub Pull Requests](https://img.shields.io/github/issues-pr/andrewvo89/zod-error?color=blue)](https://github.com/andrewvo89/zod-error/pulls)\r\n[![License](https://img.shields.io/github/license/andrewvo89/zod-error?color=blue)](/LICENSE)\r\n\r\n\u003c/div\u003e\r\n\r\n---\r\n\r\n\u003cp align=\"center\"\u003eUtilities to format and customize Zod error messages.\u003c/p\u003e\r\n\r\n## Table of Contents\r\n\r\n- [About](#about)\r\n- [Installation](#installation)\r\n- [Usage](#usage)\r\n- [Authors](#authors)\r\n- [Acknowledgments](#acknowledgements)\r\n\r\n## About\r\n\r\nZod Error converts and formats Zod Issues into a customizable error message string that can be consumed by various applications such as browser error message modals or server api error messages.\r\n\r\n[Zod v4](https://zod.dev/v4) has a simple API to stringify errors. It may be sufficient enough for your needs:\r\nhttps://zod.dev/error-formatting?id=zprettifyerror\r\n\r\n### Basic Usage\r\n\r\nZod Error converts an array of Zod Issues that look like this:\r\n\r\n```ts\r\n[\r\n  {\r\n    code: 'invalid_type',\r\n    expected: 'string',\r\n    received: 'undefined',\r\n    path: ['name'],\r\n    message: 'Required',\r\n  },\r\n  {\r\n    code: 'invalid_type',\r\n    expected: 'string',\r\n    received: 'number',\r\n    path: ['pets', 1],\r\n    message: 'Expected string, received number',\r\n  },\r\n];\r\n```\r\n\r\ninto this:\r\n\r\n```\r\nError #1: Code: invalid_type ~ Path: name ~ Message: Required | Error #2: Code: invalid_type ~ Path: pets[1] ~ Message: Expected string, received number\r\n```\r\n\r\n## Versions\r\n\r\nWith the release of [Zod v4](https://zod.dev/v4), `zod-error` has moved to v2 to meet the new API.\r\n| Zod | Zod Error |\r\n|-----|-----------|\r\n| 3.x.x | 1.x.x |\r\n| 4.x.x | 2.x.x |\r\n\r\n## Installation\r\n\r\nInstall the package using your favorite package manager:\r\n\r\n```\r\nnpm install zod-error\r\nyarn add zod-error\r\npnpm add zod-error\r\n```\r\n\r\n## Usage\r\n\r\n### Message Format\r\n\r\n```\r\n\r\n🕓 2022-07-14T20:19:52.290Z ~ Error #1: Code: invalid_type ~ Path: ratings[0].speed ~ Message: Expected number, received string 🔥 Error #2: Code: invalid_enum_value ~ Path: position ~ Message: Invalid enum value. Expected 'C' | 'PF' | 'SF' | 'SG' | 'PG', received 'Center'🔚\r\n\r\n```\r\n\r\n| Value                                                                                                                                               | Description                                        |\r\n| --------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- |\r\n| `🕓 2022-07-14T20:19:15.660Z ~`                                                                                                                     | Prefix                                             |\r\n| `~`                                                                                                                                                 | Component delimiter                                |\r\n| `Error #1:`                                                                                                                                         | Added using `options.transform()`                  |\r\n| `Code: `                                                                                                                                            | Code label                                         |\r\n| `invalid_type`                                                                                                                                      | Code value                                         |\r\n| `Path: `                                                                                                                                            | Path label                                         |\r\n| `ratings[0].speed`                                                                                                                                  | Path value                                         |\r\n| `Message: `                                                                                                                                         | Message label                                      |\r\n| `Expected number, received string`                                                                                                                  | Message value                                      |\r\n| `🔥`                                                                                                                                                | Error delimiter                                    |\r\n| `Error #2: Code: invalid_enum_value ~ Path: position ~ Message: Invalid enum value. Expected 'C' \\| 'PF' \\| 'SF' \\| 'SG'\\| 'PG', received 'Center'` | Error from second ZodIssue from Issues array input |\r\n| `🔚`                                                                                                                                                | Suffix                                             |\r\n\r\n### Options\r\n\r\nError messages are completely customizable from label names to delimiters, prefixes, suffixes and the inclusion/exclusion of components (code, path, message). An options argument can be passed to any Zod Error function as the last argument to customize the error message.\r\n\r\n| Property   | Value                                                             | Description                                                               |\r\n| ---------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------- |\r\n| code?      | [CodeOptions](#codeoptions)                                       | Options to customize the code component of the error message.             |\r\n| delimiter? | [DelimiterOptions](#delimiteroptions)                             | Set the delimiter between error messages and between components.          |\r\n| maxErrors? | number                                                            | Maximum amount of error messages to display in final concatenated string. |\r\n| message?   | [MessageOptions](#messageoptions)                                 | Options to customize the message component of the error message.          |\r\n| path?      | [PathOptions](#pathoptions)                                       | Options to customize the code path of the error message.                  |\r\n| prefix?    | string                                                            | Add a prefix to the start of the final concatenated message.              |\r\n| suffix?    | string                                                            | Add a suffix to the end of the final concatenated string.                 |\r\n| transform? | (params: [TransformErrorParams](#transformerrorparams)) =\u003e string | A custom function to transform the format of each error message.          |\r\n\r\n### CodeOptions\r\n\r\n| Property   | Value                                                                     | Description                                                                                             |\r\n| ---------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |\r\n| enabled    | boolean                                                                   | Display or hide the code component of the error message. Defaults to `true`.                            |\r\n| label?     | string \\| null                                                            | Set a custom label. Defaults to `Code: `. Only available if `enabled` is `true`.                        |\r\n| transform? | (params: [TransformComponentParams](#transformcomponentparams)) =\u003e string | A custom function to transform the format of the code component. Only available if `enabled` is `true`. |\r\n\r\n### DelimiterOptions\r\n\r\n| Property   | Value  | Description                                                                                   |\r\n| ---------- | ------ | --------------------------------------------------------------------------------------------- |\r\n| component? | string | The delimiter between each component during the concatentation process. Defaults to `~`.      |\r\n| error?     | string | The delimiter between each error message during the concatentation process. Defaults to `\\|`. |\r\n\r\n### MessageOptions\r\n\r\n| Property   | Value                                                                     | Description                                                                                                |\r\n| ---------- | ------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |\r\n| enabled    | boolean                                                                   | Display or hide the message component of the error message. Defaults to `true`.                            |\r\n| label?     | string \\| null                                                            | Set a custom label. Defaults to `Message: `. Only available if `enabled` is `true`.                        |\r\n| transform? | (params: [TransformComponentParams](#transformcomponentparams)) =\u003e string | A custom function to transform the format of the message component. Only available if `enabled` is `true`. |\r\n\r\n### PathOptions\r\n\r\n| Property             | Value                                                                     | Description                                                                                                                                                              |\r\n| -------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\r\n| arraySquareBrackets? | boolean                                                                   | Adds square brackets around index number in the path. Only available if `enabled` is `true` and `type` is `objectNotation` or `breadcrumbs`. Defaults to `true`.         |\r\n| delimiter?           | string                                                                    | Set a custom delimeter between each path element. Only available if `enabled` is `true` and `type` is `breadcrumbs`. Defaults to `\u003e`.                                    |\r\n| enabled              | boolean                                                                   | Display or hide the path component of the error message. Defaults to `true`.                                                                                             |\r\n| label?               | string \\| null                                                            | Set a custom label. Defaults to `Message: `. Only available if `enabled` is `true`.                                                                                      |\r\n| transform?           | (params: [TransformComponentParams](#transformcomponentparams)) =\u003e string | A custom function to transform the format of the message component. Only available if `enabled` is `true`.                                                               |\r\n| type                 | 'objectNotation' \\| 'zodPathArray' \\| 'breadcrumbs'                       | Sets the style of the path string.\u003cbr/\u003eobjectNotation = car.wheels[1].tyre \u003cbr/\u003ezodPathArray = [\"car\", \"wheels\", 1, \"tyre\"]\u003cbr/\u003ebreadcrumbs = car \u003e wheels \u003e [1] \u003e tyre. |\r\n\r\n### TransformComponentParams\r\n\r\n| Property  | Value  | Description                                                       |\r\n| --------- | ------ | ----------------------------------------------------------------- |\r\n| component | string | The transformed component string. Defaults to `${label}${value}`. |\r\n| label     | string | The label of the component.                                       |\r\n| value     | string | The value of the component.                                       |\r\n\r\n### TransformErrorParams\r\n\r\n| Property         | Value            | Description                                                               |\r\n| ---------------- | ---------------- | ------------------------------------------------------------------------- |\r\n| codeComponent    | string           | The transformed code component string. Defaults to `${label}${value}`.    |\r\n| errorMessage     | string           | The transformed error message consisting of all components concatentated. |\r\n| index            | string           | The index of the current error message.                                   |\r\n| issue            | z.core.$ZodIssue | The original ZodIssue object.                                             |\r\n| messageComponent | string           | The transformed message component string. Defaults to `${label}${value}`. |\r\n| pathComponent    | string           | The transformed path component string. Defaults to `${label}${value}`.    |\r\n\r\n### Examples\r\n\r\nThere are 6 ways to consume Zod Error. `generateErrorMessage()`, `generateError()`, `parse()`, `parseAsync()`, `safeParse()` and `safeParseAsync()`.\r\n\r\n#### `generateErrorMessage(issues: z.core.$ZodIssue[], options?: ErrorMessageOptions): string`\r\n\r\nFormats an array of Zod Issues as a result of `z.parse()`, `z.parseAsync()`, `z.safeParse()` or `z.safeParseAsync()` and outputs as a single string. Multiple errors are concatenated into a single readable string.\r\n\r\n```ts\r\nimport { generateErrorMessage, ErrorMessageOptions } from 'zod-error';\r\nimport { z } from 'zod';\r\n\r\nenum Color {\r\n  Red = 'Red',\r\n  Blue = 'Blue',\r\n}\r\n\r\nconst options: ErrorMessageOptions = {\r\n  delimiter: {\r\n    error: ' 🔥 ',\r\n  },\r\n  transform: ({ errorMessage, index }) =\u003e `Error #${index + 1}: ${errorMessage}`,\r\n};\r\n\r\nconst schema = z.object({\r\n  color: z.enum(Color),\r\n  shape: z.string(),\r\n  size: z.number().gt(0),\r\n});\r\n\r\nconst data = {\r\n  color: 'Green',\r\n  size: -1,\r\n};\r\n\r\nconst result = schema.safeParse(data);\r\nif (!result.success) {\r\n  const errorMessage = generateErrorMessage(result.error.issues, options);\r\n  throw new Error(errorMessage);\r\n}\r\n```\r\n\r\nError Message:\r\n\r\n```\r\nError #1: Code: invalid_enum_value ~ Path: color ~ Message: Invalid enum value. Expected 'Red' | 'Blue', received 'Green' 🔥 Error #2: Code: invalid_type ~ Path: shape ~ Message: Required 🔥 Error #3: Code: too_small ~ Path: size ~ Message: Number must be greater than 0\r\n```\r\n\r\n#### `generateError(issues: z.core.$ZodIssue[], options?: ErrorMessageOptions): Error`\r\n\r\nFormats an array of Zod Issues as a result of `z.parse()`, `z.parseAsync()`, `z.safeParse()` or `z.safeParseAsync()` and outputs as a JavaScript Error object. Multiple errors are concatenated into a single readable string.\r\n\r\n```ts\r\nimport { ErrorMessageOptions, generateError } from 'zod-error';\r\nimport { z } from 'zod';\r\n\r\nconst options: ErrorMessageOptions = {\r\n  maxErrors: 2,\r\n  delimiter: {\r\n    component: ' - ',\r\n  },\r\n  path: {\r\n    enabled: true,\r\n    type: 'zodPathArray',\r\n    label: 'Zod Path: ',\r\n  },\r\n  code: {\r\n    enabled: false,\r\n  },\r\n  message: {\r\n    enabled: true,\r\n    label: '',\r\n  },\r\n};\r\n\r\nconst schema = z.object({\r\n  dates: z.object({\r\n    purchased: z.date(),\r\n    fulfilled: z.date(),\r\n  }),\r\n  item: z.string(),\r\n  price: z.number(),\r\n});\r\n\r\nconst data = {\r\n  dates: { purchased: 'yesterday' },\r\n  item: 1,\r\n  price: '1,000',\r\n};\r\n\r\ntry {\r\n  schema.parse(data);\r\n} catch (error) {\r\n  const genericError = generateError(error, options);\r\n  throw genericError;\r\n}\r\n```\r\n\r\nError Message:\r\n\r\n```\r\nZod Path: [\"dates\", \"purchased\"] - Expected date, received string | Zod Path: [\"dates\", \"fulfilled\"] - Required\r\n```\r\n\r\n#### `parse\u003cT extends z.ZodTypeAny\u003e(schema: T, data: unknown, options?: ErrorMessageOptions): T['_output']`\r\n\r\nReplaces Zod's `.parse()` function by replacing Zod's `ZodError` with a generic JavaScript `Error` object where the custom formatted message can be accessed on `error.message`.\r\n\r\n```ts\r\nimport { ErrorMessageOptions, parse } from 'zod-error';\r\nimport { z } from 'zod';\r\n\r\nconst options: ErrorMessageOptions = {\r\n  delimiter: {\r\n    error: ' ',\r\n  },\r\n  path: {\r\n    enabled: true,\r\n    type: 'objectNotation',\r\n    transform: ({ label, value }) =\u003e `\u003c${label}: ${value}\u003e`,\r\n  },\r\n  code: {\r\n    enabled: true,\r\n    transform: ({ label, value }) =\u003e `\u003c${label}: ${value}\u003e`,\r\n  },\r\n  message: {\r\n    enabled: true,\r\n    transform: ({ label, value }) =\u003e `\u003c${label}: ${value}\u003e`,\r\n  },\r\n  transform: ({ errorMessage }) =\u003e `👉 ${errorMessage} 👈`,\r\n};\r\n\r\nconst schema = z.object({\r\n  animal: z.enum(['🐶', '🐱', '🐵']),\r\n  quantity: z.number().gte(1),\r\n});\r\n\r\nconst data = {\r\n  animal: '🐼',\r\n  quantity: 0,\r\n};\r\n\r\ntry {\r\n  const safeData = parse(schema, data, options);\r\n  /**\r\n   * Asynchronous version\r\n   * const safeData = await parseAsync(schema, data, options);\r\n   */\r\n} catch (error) {\r\n  /**\r\n   * Replaces ZodError with a JavaScript\r\n   * Error object with custom formatted message.\r\n   */\r\n  if (error instanceof Error) {\r\n    console.error(error.message);\r\n  }\r\n}\r\n```\r\n\r\nError Message:\r\n\r\n```\r\n👉 \u003cCode: : invalid_enum_value\u003e ~ \u003cPath: : animal\u003e ~ \u003cMessage: : Invalid enum value. Expected '🐶' | '🐱' | '🐵', received '🐼'\u003e 👈 👉 \u003cCode: : too_small\u003e ~ \u003cPath: : quantity\u003e ~ \u003cMessage: : Number must be greater than or equal to 1\u003e 👈\r\n```\r\n\r\nNote:\r\n\r\n\u003e If your schema contains an async `.refine()` or `.transform()` function, use `parseAsync()` instead.\r\n\r\n#### `safeParse\u003cT extends z.ZodTypeAny\u003e(schema: T, data: unknown, options?: ErrorMessageOptions): SafeParseReturnType\u003cT['_output']`\r\n\r\nReplaces Zod's `.safeParse()` function by replacing Zod's `SafeParseReturnType` with a similar return type where if `result.success` is `false`, the custom formatted error message will be available on `result.error.message`.\r\n\r\n```ts\r\nimport { ErrorMessageOptions, safeParse } from 'zod-error';\r\nimport { z } from 'zod';\r\n\r\nconst options: ErrorMessageOptions = {\r\n  prefix: `Time: ${new Date().toISOString()} ~ `,\r\n  suffix: '🔚',\r\n};\r\n\r\nconst schema = z.object({\r\n  id: z.uuid(),\r\n  timestamp: z.number(),\r\n  message: z.string().min(5),\r\n});\r\n\r\nconst data = {\r\n  id: 'ID001',\r\n  timestamp: new Date(),\r\n  message: 'lol!',\r\n};\r\n\r\nconst result = safeParse(schema, data, options);\r\n/**\r\n * Asynchronous version\r\n * const result = await safeParseAsync(schema, data, options);\r\n */\r\nif (!result.success) {\r\n  /**\r\n   * Replaces Zod's error object with custom\r\n   * error object with formatted message.\r\n   */\r\n  const message = result.error.message;\r\n  console.error(message);\r\n} else {\r\n  const safeData = result.data;\r\n}\r\n```\r\n\r\nError Message:\r\n\r\n```\r\nTime: 2022-07-14T11:10:10.602Z ~ Code: invalid_string ~ Path: id ~ Message: Invalid uuid | Code: invalid_type ~ Path: timestamp ~ Message: Expected number, received date | Code: too_small ~ Path: message ~ Message: String must contain at least 5 character(s)🔚\r\n```\r\n\r\nNote:\r\n\r\n\u003e If your schema contains an async `.refine()` or `.transform()` function, use `safeParseAsync()` instead.\r\n\r\n## Authors\r\n\r\n- [@andrewvo89](https://github.com/andrewvo89) - Idea \u0026 Initial work.\r\n\r\nSee also the list of [contributors](https://github.com/andrewvo89/zod-error/contributors) who participated in this project.\r\n\r\n## Acknowledgements\r\n\r\n- [Zod](https://zod.dev/) for an amazing validation library.\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrewvo89%2Fzod-error","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandrewvo89%2Fzod-error","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrewvo89%2Fzod-error/lists"}