colinhacks/zod · error · Error
Symbols cannot be represented in JSON Schema
Error message
Symbols cannot be represented in JSON Schema
What it means
Symbols have no JSON serialization and therefore no JSON Schema type, so `symbolProcessor` (json-schema-processors.ts:108) refuses `z.symbol()`. Like the other unrepresentable processors, it throws only when `ctx.unrepresentable === "throw"` (the default) and is silenced by `unrepresentable: "any"`.
Source
Thrown at packages/zod/src/v4/core/json-schema-processors.ts:110
json.maximum = maximum;
}
if (typeof multipleOf === "number") json.multipleOf = multipleOf;
};
export const booleanProcessor: Processor<schemas.$ZodBoolean> = (_schema, _ctx, json, _params) => {
(json as JSONSchema.BooleanSchema).type = "boolean";
};
export const bigintProcessor: Processor<schemas.$ZodBigInt> = (_schema, ctx, _json, _params) => {
if (ctx.unrepresentable === "throw") {
throw new Error("BigInt cannot be represented in JSON Schema");
}
};
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");
}
};View on GitHub (pinned to 912f0f51b0)
Solutions
- Call `z.toJSONSchema(schema, { unrepresentable: "any" })` to emit an empty schema for symbol nodes.
- Drop or replace the symbol field with a string enum before conversion if the contract needs to be concrete.
- Split the symbol field out of the converted subtree and document it separately.
Example fix
// before
z.toJSONSchema(z.object({ tag: z.symbol() })); // throws
// after
z.toJSONSchema(z.object({ tag: z.symbol() }), { unrepresentable: "any" }); Defensive patterns
Strategy: fallback
Validate before calling
const json = z.toJSONSchema(schema, { unrepresentable: "any" }); Type guard
function usesSymbol(schema: z.ZodType): boolean {
return schema._zod.traits.has("$ZodSymbol");
} 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
- Avoid symbol-typed fields in schemas you intend to convert to JSON Schema.
- Reserve symbols for internal/runtime-only metadata, not contract fields.
- Standardize on `{ unrepresentable: "any" }` for heterogeneous schemas.
When it happens
Trigger: Running `z.toJSONSchema()` over a schema containing `z.symbol()`, with default options. Common when a schema reuses a symbol field as a discriminator or sentinel.
Common situations: Generating docs/contracts for a schema that includes symbol-typed fields; converting a meta-schema that uses symbols as opaque tokens.
Related errors
- BigInt 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
- Custom types cannot be represented in JSON Schema
AI-assisted analysis of colinhacks/zod@912f0f51b0 (2026-08-03).
Data as JSON: /data/errors/05a50cbb8b81626b.json.
Report an issue: GitHub.