colinhacks/zod · error · Error
Date cannot be represented in JSON Schema
Error message
Date cannot be represented in JSON Schema
What it means
JSON has no native date type (dates are conventionally ISO strings), so Zod will not guess a representation: `dateProcessor` (json-schema-processors.ts:148) throws for `z.date()` when `ctx.unrepresentable === "throw"` (default). Unlike bigint/symbol, a clean replacement exists (`z.iso.datetime()` or `z.string().datetime()`).
Source
Thrown at packages/zod/src/v4/core/json-schema-processors.ts:150
throw new Error("Void cannot be represented in JSON Schema");
}
};
export const neverProcessor: Processor<schemas.$ZodNever> = (_schema, _ctx, json, _params) => {
json.not = {};
};
export const anyProcessor: Processor<schemas.$ZodAny> = (_schema, _ctx, _json, _params) => {
// empty schema accepts anything
};
export const unknownProcessor: Processor<schemas.$ZodUnknown> = (_schema, _ctx, _json, _params) => {
// empty schema accepts anything
};
export const dateProcessor: Processor<schemas.$ZodDate> = (_schema, ctx, _json, _params) => {
if (ctx.unrepresentable === "throw") {
throw new Error("Date cannot be represented in JSON Schema");
}
};
export const enumProcessor: Processor<schemas.$ZodEnum> = (schema, _ctx, json, _params) => {
const def = schema._zod.def as schemas.$ZodEnumDef;
const values = getEnumValues(def.entries);
// Number enums can have both string and number values
if (values.every((v) => typeof v === "number")) json.type = "number";
if (values.every((v) => typeof v === "string")) json.type = "string";
json.enum = values;
};
export const literalProcessor: Processor<schemas.$ZodLiteral> = (schema, ctx, json, _params) => {
const def = schema._zod.def as schemas.$ZodLiteralDef<any>;
const vals: (string | number | boolean | null)[] = [];
for (const val of def.values) {
if (val === undefined) {
if (ctx.unrepresentable === "throw") {View on GitHub (pinned to 912f0f51b0)
Solutions
- For conversion only, call `z.toJSONSchema(schema, { unrepresentable: "any" })`.
- Preferably replace `z.date()` with `z.iso.datetime()` (or `z.string().datetime()`) so the contract uses the standard `date-time` JSON Schema format.
- Keep `z.date()` at the runtime boundary and pipe/transform into a datetime string schema for the contract.
Example fix
// before
z.toJSONSchema(z.object({ createdAt: z.date() })); // throws
// after
z.toJSONSchema(z.object({ createdAt: z.iso.datetime() })); // -> { type: "string", format: "date-time" } Defensive patterns
Strategy: fallback
Validate before calling
// Prefer a JSON-native datetime for contract schemas.
const contractSchema = z.object({ createdAt: z.iso.datetime() });
const json = z.toJSONSchema(contractSchema); Type guard
function usesDate(schema: z.ZodType): boolean {
return schema._zod.traits.has("$ZodDate");
} 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
- Use `z.iso.datetime()` for any field that will be converted to JSON Schema.
- Keep `z.date()` only at the runtime boundary and pipe into a datetime string for contracts.
- Standardize `{ unrepresentable: "any" }` for mixed schemas containing dates.
When it happens
Trigger: `z.toJSONSchema()` over a schema containing `z.date()`, with default options. Very common in API schemas that model timestamps as JS Date objects.
Common situations: Generating OpenAPI for an endpoint that returns Date objects; sharing a Zod schema between a Node backend (uses Date) and a JSON Schema consumer.
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
- Custom types cannot be represented in JSON Schema
AI-assisted analysis of colinhacks/zod@912f0f51b0 (2026-08-03).
Data as JSON: /data/errors/168b5634da54477b.json.
Report an issue: GitHub.