colinhacks/zod · error · Error
Map cannot be represented in JSON Schema
Error message
Map cannot be represented in JSON Schema
What it means
JSON objects only support string keys, so a `Map` (arbitrary keys) cannot be represented; `mapProcessor` (json-schema-processors.ts:262) throws for `z.map(keyType, valType)` when `ctx.unrepresentable === "throw"` (default).
Source
Thrown at packages/zod/src/v4/core/json-schema-processors.ts:264
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");
}
};
// ==================== COMPOSITE TYPE PROCESSORS ====================
export const arrayProcessor: Processor<schemas.$ZodArray> = (schema, ctx, _json, params) => {
const json = _json as JSONSchema.ArraySchema;
const def = schema._zod.def as schemas.$ZodArrayDef;
const { minimum, maximum } = schema._zod.bag;
if (typeof minimum === "number") json.minItems = minimum;
if (typeof maximum === "number") json.maxItems = maximum;
View on GitHub (pinned to 912f0f51b0)
Solutions
- Pass `{ unrepresentable: "any" }` to emit an empty schema for the map node.
- Re-model as `z.record(z.string(), valueType)` which produces a valid JSON Schema object type.
- If keys are non-string, map them to strings at the boundary and use a record schema.
Example fix
// before
z.toJSONSchema(z.map(z.string(), z.number())); // throws
// after
z.toJSONSchema(z.record(z.string(), z.number())); // -> { type: "object", additionalProperties: { type: "number" } } Defensive patterns
Strategy: fallback
Validate before calling
// Use z.record for dictionary-shaped data in contract schemas. const contractSchema = z.record(z.string(), z.number()); const json = z.toJSONSchema(contractSchema);
Type guard
function usesMap(schema: z.ZodType): boolean {
return schema._zod.traits.has("$ZodMap");
} 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
- Model dictionaries as `z.record(z.string(), valueType)` rather than `z.map()` for JSON contracts.
- Stringify non-string keys at the boundary when the source uses a Map.
- Use `{ unrepresentable: "any" }` for runtime schemas that must retain Map.
When it happens
Trigger: `z.toJSONSchema()` over a schema containing `z.map(z.string(), z.number())`, with default options.
Common situations: Generating contracts for schemas that model dictionaries/lookup tables as JS Maps; converting a schema shared with a backend that uses Map.
Related errors
- BigInt cannot be represented in JSON Schema
- Symbols 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
AI-assisted analysis of colinhacks/zod@912f0f51b0 (2026-08-03).
Data as JSON: /data/errors/33ed11f9b31c922b.json.
Report an issue: GitHub.