colinhacks/zod · error · Error

Void cannot be represented in JSON Schema

Error message

Void cannot be represented in JSON Schema

What it means

Thrown by toJSONSchema() when a ZodVoid schema (z.void()) is encountered with unrepresentable 'throw' (default). void denotes 'return value ignored' (typically function return types); it has no JSON Schema analogue.

Solutions

  1. Pass { unrepresentable: 'any' } to toJSONSchema() so void fields become {}.
  2. Drop the function/void portions before exporting; export only the data-carrying parts of the schema.
  3. Model 'no meaningful return' externally as an empty object schema or omit the field.

Example fix

// before (throws)
const Schema = z.object({ ack: z.void() });
z.toJSONSchema(Schema);

// after
z.toJSONSchema(Schema, { unrepresentable: 'any' });
Defensive patterns

Strategy: try-catch

Validate before calling

const opts = schemaContains(schema, (s) => s._zod.def.type === 'void')
  ? { unrepresentable: 'any' }
  : {};
const json = z.toJSONSchema(schema, opts);

Type guard

function hasVoid(schema) {
  return schema._zod.def.type === 'void';
}

Try / catch

try {
  return z.toJSONSchema(schema);
} catch (e) {
  if (e.message === 'Void cannot be represented in JSON Schema') {
    return z.toJSONSchema(schema, { unrepresentable: 'any' });
  }
  throw e;
}

Prevention

When it happens

Trigger: Exporting a schema that includes a z.void() field — often the return type of a z.function() — to JSON Schema. Reusing a function-arity schema (whose arguments/return include z.void()) for documentation.

Common situations: RPC-style schemas where z.function(args, z.void()) models a procedure, then trying to serialise the whole shape for OpenAPI.

Related errors


AI-assisted analysis of colinhacks/zod@2d90846af9 (2026-08-11). Data as JSON: /api/errors/f191ee175a5924ec. Report an issue: GitHub.

Appendix: 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 2d90846af9)