{"id":"33ed11f9b31c922b","repo":"colinhacks/zod","slug":"map-cannot-be-represented-in-json-schema","errorCode":null,"errorMessage":"Map cannot be represented in JSON Schema","messagePattern":"Map cannot be represented in JSON Schema","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/zod/src/v4/core/json-schema-processors.ts","lineNumber":264,"sourceCode":"    throw new Error(\"Custom types cannot be represented in JSON Schema\");\n  }\n};\n\nexport const functionProcessor: Processor<schemas.$ZodFunction> = (_schema, ctx, _json, _params) => {\n  if (ctx.unrepresentable === \"throw\") {\n    throw new Error(\"Function types cannot be represented in JSON Schema\");\n  }\n};\n\nexport const transformProcessor: Processor<schemas.$ZodTransform> = (_schema, ctx, _json, _params) => {\n  if (ctx.unrepresentable === \"throw\") {\n    throw new Error(\"Transforms cannot be represented in JSON Schema\");\n  }\n};\n\nexport const mapProcessor: Processor<schemas.$ZodMap> = (_schema, ctx, _json, _params) => {\n  if (ctx.unrepresentable === \"throw\") {\n    throw new Error(\"Map cannot be represented in JSON Schema\");\n  }\n};\n\nexport const setProcessor: Processor<schemas.$ZodSet> = (_schema, ctx, _json, _params) => {\n  if (ctx.unrepresentable === \"throw\") {\n    throw new Error(\"Set cannot be represented in JSON Schema\");\n  }\n};\n\n// ==================== COMPOSITE TYPE PROCESSORS ====================\n\nexport const arrayProcessor: Processor<schemas.$ZodArray> = (schema, ctx, _json, params) => {\n  const json = _json as JSONSchema.ArraySchema;\n  const def = schema._zod.def as schemas.$ZodArrayDef;\n  const { minimum, maximum } = schema._zod.bag;\n  if (typeof minimum === \"number\") json.minItems = minimum;\n  if (typeof maximum === \"number\") json.maxItems = maximum;\n","sourceCodeStart":246,"sourceCodeEnd":282,"githubUrl":"https://github.com/colinhacks/zod/blob/912f0f51b0ced654d0069741e7160834dca742ee/packages/zod/src/v4/core/json-schema-processors.ts#L246-L282","documentation":"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).","triggerScenarios":"`z.toJSONSchema()` over a schema containing `z.map(z.string(), z.number())`, with default options.","commonSituations":"Generating contracts for schemas that model dictionaries/lookup tables as JS Maps; converting a schema shared with a backend that uses Map.","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."],"exampleFix":"// before\nz.toJSONSchema(z.map(z.string(), z.number())); // throws\n// after\nz.toJSONSchema(z.record(z.string(), z.number())); // -> { type: \"object\", additionalProperties: { type: \"number\" } }","handlingStrategy":"fallback","validationCode":"// Use z.record for dictionary-shaped data in contract schemas.\nconst contractSchema = z.record(z.string(), z.number());\nconst json = z.toJSONSchema(contractSchema);","typeGuard":"function usesMap(schema: z.ZodType): boolean {\n  return schema._zod.traits.has(\"$ZodMap\");\n}","tryCatchPattern":"try {\n  return z.toJSONSchema(schema);\n} catch (e) {\n  if (e instanceof Error && /cannot be represented in JSON Schema/.test(e.message)) {\n    return z.toJSONSchema(schema, { unrepresentable: \"any\" });\n  }\n  throw e;\n}","preventionTips":["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."],"tags":["json-schema","map","record","unrepresentable","openapi"],"analyzedSha":"912f0f51b0ced654d0069741e7160834dca742ee","analyzedAt":"2026-08-03T17:41:55.908Z","schemaVersion":2}