colinhacks/zod · error · Error
Undefined cannot be represented in JSON Schema
Error message
Undefined cannot be represented in JSON Schema
What it means
`undefined` is not a JSON value, so `undefinedProcessor` (json-schema-processors.ts:124) will not convert `z.undefined()`. It throws when `ctx.unrepresentable === "throw"` (default). Use `unrepresentable: "any"` to skip, or model the field as optional/omitted instead.
Source
Thrown at packages/zod/src/v4/core/json-schema-processors.ts:126
export const symbolProcessor: Processor<schemas.$ZodSymbol> = (_schema, ctx, _json, _params) => {
if (ctx.unrepresentable === "throw") {
throw new Error("Symbols cannot be represented in JSON Schema");
}
};
export const nullProcessor: Processor<schemas.$ZodNull> = (_schema, ctx, json, _params) => {
if (ctx.target === "openapi-3.0") {
json.type = "string";
json.nullable = true;
json.enum = [null];
} else {
json.type = "null";
}
};
export const undefinedProcessor: Processor<schemas.$ZodUndefined> = (_schema, ctx, _json, _params) => {
if (ctx.unrepresentable === "throw") {
throw new Error("Undefined cannot be represented in JSON Schema");
}
};
export const voidProcessor: Processor<schemas.$ZodVoid> = (_schema, ctx, _json, _params) => {
if (ctx.unrepresentable === "throw") {
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) => {View on GitHub (pinned to 912f0f51b0)
Solutions
- Pass `{ unrepresentable: "any" }` to `z.toJSONSchema()`.
- Re-model the field as optional (`.optional()`) or omit it from the object shape, since JSON omits absent keys rather than encoding undefined.
- Use `z.null()` if the JSON representation should be explicit `null`.
Example fix
// before
z.toJSONSchema(z.object({ x: z.undefined() })); // throws
// after
z.toJSONSchema(z.object({ x: z.undefined().optional() }), { unrepresentable: "any" }); Defensive patterns
Strategy: fallback
Validate before calling
const json = z.toJSONSchema(schema, { unrepresentable: "any" }); Type guard
function usesUndefined(schema: z.ZodType): boolean {
return schema._zod.traits.has("$ZodUndefined");
} 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
- Prefer `.optional()` over `z.undefined()` to model absent fields.
- Use `{ unrepresentable: "any" }` when converting schemas that include undefined sentinels.
- Map absence to `null` in JSON contracts where an explicit value is needed.
When it happens
Trigger: `z.toJSONSchema()` over a schema containing `z.undefined()` (a field whose only valid value is `undefined`), with default options. Often appears in tuple/union branches or explicit undefined sentinels.
Common situations: Generating a contract for a schema that models the absence of a value with `z.undefined()`; converting a discriminated union where one branch is literally undefined.
Related errors
- BigInt cannot be represented in JSON Schema
- Symbols cannot be represented in JSON Schema
- Void cannot be represented in JSON Schema
- Date cannot be represented in JSON Schema
- Literal `undefined` cannot be represented in JSON Schema
AI-assisted analysis of colinhacks/zod@912f0f51b0 (2026-08-03).
Data as JSON: /data/errors/daeb7c79fde9cf18.json.
Report an issue: GitHub.