|
| 1 | +--- |
| 2 | +title: "Zod" |
| 3 | +description: "Resolve Zod typechecking, test, and deployment errors when upgrading to Trigger.dev v4.6." |
| 4 | +--- |
| 5 | + |
| 6 | +**Trigger.dev v4.6 uses Zod 4 by default. Zod 3.25.56 and later 3.x releases remain supported.** |
| 7 | + |
| 8 | +Use this guide if typechecking, tests, or deployment fail after upgrading. The supported project dependency range is `^3.25.56 || ^4.0.0`. |
| 9 | + |
| 10 | +| Your project's Zod dependency | What to do | |
| 11 | +| --- | --- | |
| 12 | +| No direct Zod dependency | No Zod-specific change is needed. Trigger.dev installs a compatible runtime dependency automatically. | |
| 13 | +| Zod below 3.25.56 | Upgrade before using Trigger.dev v4.6. These versions are unsupported. | |
| 14 | +| Zod 3.25.56 or later in the 3.x release line | Keep using your Zod 3 schemas with supported SDK APIs. Review the cross-major caveats below. | |
| 15 | +| Zod 4.x | Supported and the recommended default. | |
| 16 | + |
| 17 | +Passing your own supported Zod 3 schema to [`schemaTask`](/tasks/schemaTask) or `toolTask` remains supported. This does not make Zod 3 and Zod 4 schemas interchangeable when you compose or inspect them yourself. |
| 18 | + |
| 19 | +## Typechecking, tests, or deployment fail after upgrading |
| 20 | + |
| 21 | +An older Zod installation can be missing the entry points, types, or schema behavior that Trigger.dev v4.6 requires. |
| 22 | + |
| 23 | +Expect TypeScript errors when an unsupported version is resolved, particularly with `skipLibCheck: false`. Tests may also fail when they import or execute schemas. Deployment loads your task code, so an incompatible runtime installation causes deployment errors even if your local tooling skips typechecking. A passing local test suite does not establish that an unsupported version is safe to deploy. |
| 24 | + |
| 25 | +Symptoms include missing `zod/v4` or `zod/v4/core` exports, missing Zod types, incompatible generic parameters, and errors while loading tasks. The exact failure depends on the version and dependency tree; not every unsupported version fails at the same stage. |
| 26 | + |
| 27 | +### Check the installed version |
| 28 | + |
| 29 | +Inspect the resolved dependencies in the package that contains your tasks, not only the version range in `package.json`: |
| 30 | + |
| 31 | +<CodeGroup> |
| 32 | +```bash npm |
| 33 | +npm ls zod |
| 34 | +``` |
| 35 | + |
| 36 | +```bash pnpm |
| 37 | +pnpm why zod |
| 38 | +``` |
| 39 | + |
| 40 | +```bash bun |
| 41 | +bun pm ls --all |
| 42 | +``` |
| 43 | +</CodeGroup> |
| 44 | + |
| 45 | +Check the lockfile and any dependency overrides or resolutions as well. An override can keep an old Zod version installed even after you update a direct dependency. |
| 46 | + |
| 47 | +### Update Zod |
| 48 | + |
| 49 | +Choose whether to move your application to Zod 4 or keep its existing Zod 3 schemas: |
| 50 | + |
| 51 | +<Tabs> |
| 52 | + <Tab title="Move to Zod 4"> |
| 53 | + Install the latest Zod 4 release: |
| 54 | + |
| 55 | + <CodeGroup> |
| 56 | + ```bash npm |
| 57 | + npm install zod@4 |
| 58 | + ``` |
| 59 | + |
| 60 | + ```bash pnpm |
| 61 | + pnpm add zod@4 |
| 62 | + ``` |
| 63 | + |
| 64 | + ```bash bun |
| 65 | + bun add zod@4 |
| 66 | + ``` |
| 67 | + </CodeGroup> |
| 68 | + |
| 69 | + Review [Zod's migration guide](https://zod.dev/v4/changelog) for changes to your own schemas and error handling. |
| 70 | + </Tab> |
| 71 | + <Tab title="Stay on Zod 3"> |
| 72 | + Install the latest Zod 3 patch rather than pinning the minimum supported version: |
| 73 | + |
| 74 | + <CodeGroup> |
| 75 | + ```bash npm |
| 76 | + npm install zod@3 |
| 77 | + ``` |
| 78 | + |
| 79 | + ```bash pnpm |
| 80 | + pnpm add zod@3 |
| 81 | + ``` |
| 82 | + |
| 83 | + ```bash bun |
| 84 | + bun add zod@3 |
| 85 | + ``` |
| 86 | + </CodeGroup> |
| 87 | + |
| 88 | + Your existing `import { z } from "zod"` continues to use Zod 3. Trigger.dev's own schemas use the Zod 4 implementation included in the supported Zod 3 package. |
| 89 | + </Tab> |
| 90 | +</Tabs> |
| 91 | + |
| 92 | +Other dependencies can require a higher minimum than Trigger.dev. For example, an AI SDK dependency may require Zod 3.25.76 or Zod 4. Meet those peer requirements too; do not force a lower version across every dependency. |
| 93 | + |
| 94 | +### Verify the update |
| 95 | + |
| 96 | +- Commit the updated manifest and lockfile, and make sure CI uses them. |
| 97 | +- Recheck the installed Zod versions in your local and deployment environments. |
| 98 | +- Run your project's TypeScript checks and tests, including code that constructs or inspects schemas. |
| 99 | +- Keep the CLI and SDK versions aligned using the [package upgrade guide](/upgrading-packages), then retry deployment. |
| 100 | + |
| 101 | +Do not use `skipLibCheck` or ignored peer-dependency warnings as a compatibility fix. They do not change the runtime package that deployment loads. You do not need to add Zod as a direct dependency if your application does not import it. |
| 102 | + |
| 103 | +## Parsing still fails with a supported Zod 3 version |
| 104 | + |
| 105 | +Supporting a Zod 3 schema as an SDK input is different from nesting a Trigger.dev-exported Zod 4 schema inside a Zod 3 object. Cross-major composition can fail during typechecking or parsing. |
| 106 | + |
| 107 | +For example, this mixes a Zod 3 object with a Zod 4 `RetryOptions` schema: |
| 108 | + |
| 109 | +```ts incompatible-schemas.ts |
| 110 | +import { z } from "zod"; // Project dependency is Zod 3. |
| 111 | +import { RetryOptions } from "@trigger.dev/core/v3"; |
| 112 | + |
| 113 | +const schema = z.object({ retry: RetryOptions }); |
| 114 | +schema.parse({ retry: {} }); |
| 115 | +``` |
| 116 | + |
| 117 | +Use Zod 4 for every schema in the composed object. The `zod/v4` entry point is available in both supported Zod 3 packages and Zod 4 packages: |
| 118 | + |
| 119 | +```ts compatible-schemas.ts |
| 120 | +import { z } from "zod/v4"; |
| 121 | +import { RetryOptions } from "@trigger.dev/core/v3"; |
| 122 | + |
| 123 | +const schema = z.object({ retry: RetryOptions }); |
| 124 | +schema.parse({ retry: {} }); |
| 125 | +``` |
| 126 | + |
| 127 | +Alternatively, keep the Zod 3 and Trigger.dev schemas separate and call each schema's parser independently. You do not need to migrate unrelated application schemas to use this approach. |
| 128 | + |
| 129 | +## An `instanceof` check stops matching |
| 130 | + |
| 131 | +A Zod 4 error is not an instance of the Zod 3 `ZodError` constructor. A constructor check against your project's Zod 3 import can stop matching errors produced by Trigger.dev's schemas: |
| 132 | + |
| 133 | +```ts mismatched-error-check.ts |
| 134 | +import { z } from "zod"; // Project dependency is Zod 3. |
| 135 | +import { RetryOptions } from "@trigger.dev/core/v3"; |
| 136 | + |
| 137 | +const result = RetryOptions.safeParse({ maxAttempts: "invalid" }); |
| 138 | + |
| 139 | +if (!result.success) { |
| 140 | + console.log(result.error instanceof z.ZodError); // false |
| 141 | +} |
| 142 | +``` |
| 143 | + |
| 144 | +Use the result returned by the schema you called instead of a constructor from another Zod installation: |
| 145 | + |
| 146 | +```ts schema-error-handling.ts |
| 147 | +import { RetryOptions } from "@trigger.dev/core/v3"; |
| 148 | + |
| 149 | +const result = RetryOptions.safeParse({ maxAttempts: "invalid" }); |
| 150 | + |
| 151 | +if (!result.success) { |
| 152 | + console.error(result.error.issues); |
| 153 | +} |
| 154 | +``` |
| 155 | + |
| 156 | +The same caveat applies to checks such as `schema instanceof z.ZodObject`. Multiple installed copies can also have different constructors, even within the same major version. Prefer parsing and the returned validation result over inspecting classes or private fields such as `_def`. |
| 157 | + |
| 158 | +These examples are not an exhaustive list of cross-major differences. If errors remain after updating, check which Zod implementation creates each schema and which code composes, parses, or inspects it. |
0 commit comments