colinhacks/zod · error · Error
Transforms cannot be represented in JSON Schema
Error message
Transforms cannot be represented in JSON Schema
What it means
A `z.transform()` changes the output type via an opaque function and has no static JSON Schema, so `transformProcessor` (json-schema-processors.ts:256) throws when `ctx.unrepresentable === "throw"` (default). JSON Schema describes shape, not computation.
Source
Thrown at packages/zod/src/v4/core/json-schema-processors.ts:258
export const successProcessor: Processor<schemas.$ZodSuccess> = (_schema, _ctx, json, _params) => {
(json as JSONSchema.BooleanSchema).type = "boolean";
};
export const customProcessor: Processor<schemas.$ZodCustom> = (_schema, ctx, _json, _params) => {
if (ctx.unrepresentable === "throw") {
throw new Error("Custom types cannot be represented in JSON Schema");
}
};
export const functionProcessor: Processor<schemas.$ZodFunction> = (_schema, ctx, _json, _params) => {
if (ctx.unrepresentable === "throw") {
throw new Error("Function types cannot be represented in JSON Schema");
}
};
export const transformProcessor: Processor<schemas.$ZodTransform> = (_schema, ctx, _json, _params) => {
if (ctx.unrepresentable === "throw") {
throw new Error("Transforms cannot be represented in JSON Schema");
}
};
export const mapProcessor: Processor<schemas.$ZodMap> = (_schema, ctx, _json, _params) => {
if (ctx.unrepresentable === "throw") {
throw new Error("Map cannot be represented in JSON Schema");
}
};
export const setProcessor: Processor<schemas.$ZodSet> = (_schema, ctx, _json, _params) => {
if (ctx.unrepresentable === "throw") {
throw new Error("Set cannot be represented in JSON Schema");
}
};
// ==================== COMPOSITE TYPE PROCESSORS ====================
export const arrayProcessor: Processor<schemas.$ZodArray> = (schema, ctx, _json, params) => {View on GitHub (pinned to 912f0f51b0)
Solutions
- Pass `{ unrepresentable: "any" }` so transform nodes emit an empty schema.
- Generate the contract from the input schema before the transform (use `io: "input"`), or keep a separate clean schema for the contract.
- Replace the transform with a declarative schema (`z.iso.datetime()` instead of a manual `Date` transform) where possible.
Example fix
// before
z.toJSONSchema(z.string().transform((s) => Number(s))); // throws
// after
z.toJSONSchema(z.string().transform((s) => Number(s)), { unrepresentable: "any" }); Defensive patterns
Strategy: fallback
Validate before calling
// Generate the contract from the input side of a pipe/transform.
const json = z.toJSONSchema(schema, { io: "input", unrepresentable: "any" }); Type guard
function usesTransform(schema: z.ZodType): boolean {
return schema._zod.traits.has("$ZodTransform");
} Try / catch
try {
return z.toJSONSchema(schema);
} catch (e) {
if (e instanceof Error && /cannot be represented in JSON Schema/.test(e.message)) {
return z.toJSONSchema(schema, { unrepresentable: "any" });
}
throw e;
} Prevention
- Keep a clean declarative schema for contracts; apply transforms only in the runtime parse path.
- Generate from `io: "input"` when the transform's input side is declarative.
- Use `{ unrepresentable: "any" }` for schemas that must carry transforms.
When it happens
Trigger: `z.toJSONSchema()` over a schema that pipes through `z.transform(fn)` or contains a transform node, with default options. Especially common when generating output schemas for schemas built with `.transform()`.
Common situations: Reusing a parse-time transform schema (e.g. `z.string().transform(s => new Date(s))`) for OpenAPI generation; converting a schema that has both validation and transformation.
Related errors
- BigInt cannot be represented in JSON Schema
- Symbols cannot be represented in JSON Schema
- Undefined cannot be represented in JSON Schema
- Void cannot be represented in JSON Schema
- Date cannot be represented in JSON Schema
AI-assisted analysis of colinhacks/zod@912f0f51b0 (2026-08-03).
Data as JSON: /data/errors/cfcb0d093649c23d.json.
Report an issue: GitHub.