colinhacks/zod · error · Error

Function types cannot be represented in JSON Schema

Error message

Function types cannot be represented in JSON Schema

What it means

Thrown by toJSONSchema() when a ZodFunction schema (z.function(args, ret)) is encountered with unrepresentable 'throw' (default). JSON Schema describes data, not callable values, so function schemas have no representation.

Solutions

  1. Pass { unrepresentable: 'any' } to toJSONSchema() so function fields become {}.
  2. Separate the function signature from the data model: export only the argument and return schemas via toJSONSchema(), not the wrapping z.function().
  3. For OpenAPI, describe operations explicitly rather than converting z.function() schemas.

Example fix

// before (throws)
const Tool = z.object({
  name: z.string(),
  handler: z.function(z.tuple([z.string()]), z.void()),
});
z.toJSONSchema(Tool);

// after (export only the data contract)
const ToolArgs = z.tuple([z.string()]);
z.toJSONSchema(ToolArgs);
Defensive patterns

Strategy: try-catch

Validate before calling

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

Type guard

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

Try / catch

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

Prevention

When it happens

Trigger: Calling toJSONSchema() on a schema that contains a z.function() field — common in RPC/tool schemas. Exporting an entire registry that includes procedure signatures.

Common situations: Tool-calling / MCP-style schemas where the top-level model embeds handler signatures, then feeding that model to a JSON Schema-based validator or doc generator.

Related errors


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

Appendix: source

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

    }
  } else {
    Object.assign(_json, file);
  }
};

export const successProcessor: Processor<schemas.$ZodSuccess> = (_schema, _ctx, json, _params) => {
  (json as JSONSchema.BooleanSchema).type = "boolean";
};

export const customProcessor: Processor<schemas.$ZodCustom> = (_schema, ctx, _json, _params) => {
  if (ctx.unrepresentable === "throw") {
    throw new Error("Custom types cannot be represented in JSON Schema");
  }
};

export const functionProcessor: Processor<schemas.$ZodFunction> = (_schema, ctx, _json, _params) => {
  if (ctx.unrepresentable === "throw") {
    throw new Error("Function types cannot be represented in JSON Schema");
  }
};

export const transformProcessor: Processor<schemas.$ZodTransform> = (_schema, ctx, _json, _params) => {
  if (ctx.unrepresentable === "throw") {
    throw new Error("Transforms cannot be represented in JSON Schema");
  }
};

export const mapProcessor: Processor<schemas.$ZodMap> = (_schema, ctx, _json, _params) => {
  if (ctx.unrepresentable === "throw") {
    throw new Error("Map cannot be represented in JSON Schema");
  }
};

export const setProcessor: Processor<schemas.$ZodSet> = (_schema, ctx, _json, _params) => {
  if (ctx.unrepresentable === "throw") {
    throw new Error("Set cannot be represented in JSON Schema");

View on GitHub (pinned to 2d90846af9)