colinhacks/zod · error · Error

Void cannot be represented in JSON Schema

Error message

Void cannot be represented in JSON Schema

What it means

`z.void()` (the TypeScript `void` analog) has no JSON representation, so `voidProcessor` (json-schema-processors.ts:130) refuses it when `ctx.unrepresentable === "throw"` (default). Typically appears as a function-return or no-content marker in API schemas.

Source

Thrown at packages/zod/src/v4/core/json-schema-processors.ts:132

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) => {
  // 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");

View on GitHub (pinned to 912f0f51b0)

Solutions

  1. Use `{ unrepresentable: "any" }` in the `z.toJSONSchema()` call.
  2. Drop the void field from the converted schema and represent no-content at the transport layer (HTTP 204) instead.
  3. Replace `z.void()` with `z.null()` or `z.undefined().optional()` if a concrete JSON shape is required.

Example fix

// before
z.toJSONSchema(z.object({ result: z.void() })); // throws
// after
z.toJSONSchema(z.object({ result: z.void() }), { unrepresentable: "any" });
Defensive patterns

Strategy: fallback

Validate before calling

const json = z.toJSONSchema(schema, { unrepresentable: "any" });

Type guard

function usesVoid(schema: z.ZodType): boolean {
  return schema._zod.traits.has("$ZodVoid");
}

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

When it happens

Trigger: `z.toJSONSchema()` over a schema tree that includes `z.void()`, e.g. modeling an endpoint with no response body, with default options.

Common situations: Documenting a no-content (204) API response with a Zod schema; converting function schemas whose return type is void.

Related errors


AI-assisted analysis of colinhacks/zod@912f0f51b0 (2026-08-03). Data as JSON: /data/errors/f191ee175a5924ec.json. Report an issue: GitHub.