{"id":"25a6f2edda964aaa","repo":"colinhacks/zod","slug":"nan-cannot-be-represented-in-json-schema","errorCode":null,"errorMessage":"NaN cannot be represented in JSON Schema","messagePattern":"NaN 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":204,"sourceCode":"    const val = vals[0]!;\n    json.type = val === null ? (\"null\" as const) : (typeof val as any);\n    if (ctx.target === \"draft-04\" || ctx.target === \"openapi-3.0\") {\n      json.enum = [val];\n    } else {\n      json.const = val;\n    }\n  } else {\n    if (vals.every((v) => typeof v === \"number\")) json.type = \"number\";\n    if (vals.every((v) => typeof v === \"string\")) json.type = \"string\";\n    if (vals.every((v) => typeof v === \"boolean\")) json.type = \"boolean\";\n    if (vals.every((v) => v === null)) json.type = \"null\";\n    json.enum = vals;\n  }\n};\n\nexport const nanProcessor: Processor<schemas.$ZodNaN> = (_schema, ctx, _json, _params) => {\n  if (ctx.unrepresentable === \"throw\") {\n    throw new Error(\"NaN cannot be represented in JSON Schema\");\n  }\n};\n\nexport const templateLiteralProcessor: Processor<schemas.$ZodTemplateLiteral> = (schema, _ctx, json, _params) => {\n  const _json = json as JSONSchema.StringSchema;\n  const pattern = schema._zod.pattern;\n  if (!pattern) throw new Error(\"Pattern not found in template literal\");\n  _json.type = \"string\";\n  _json.pattern = pattern.source;\n};\n\nexport const fileProcessor: Processor<schemas.$ZodFile> = (schema, _ctx, json, _params) => {\n  const _json = json as JSONSchema.StringSchema;\n  const file: JSONSchema.StringSchema = {\n    type: \"string\",\n    format: \"binary\",\n    contentEncoding: \"binary\",\n  };","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/colinhacks/zod/blob/912f0f51b0ced654d0069741e7160834dca742ee/packages/zod/src/v4/core/json-schema-processors.ts#L186-L222","documentation":"`NaN` is not a valid JSON number, so `nanProcessor` (json-schema-processors.ts:202) refuses `z.nan()` when `ctx.unrepresentable === \"throw\"` (default). There is no faithful JSON Schema for 'not-a-number'.","triggerScenarios":"`z.toJSONSchema()` over a schema containing `z.nan()`, typically in a union like `z.union([z.number(), z.nan()])`, with default options.","commonSituations":"Schemas that explicitly accept NaN (e.g. from numeric parsers or ML pipelines) being converted to a shared contract.","solutions":["Use `{ unrepresentable: \"any\" }` to emit an empty schema for the NaN node.","Strip the NaN branch from the union before conversion and normalize NaN to null/-1 at the boundary.","If NaN must be representable, encode it as a sentinel string literal and document it."],"exampleFix":"// before\nz.toJSONSchema(z.union([z.number(), z.nan()])); // throws\n// after\nz.toJSONSchema(z.union([z.number(), z.nan()]), { unrepresentable: \"any\" });","handlingStrategy":"fallback","validationCode":"const json = z.toJSONSchema(schema, { unrepresentable: \"any\" });","typeGuard":"function usesNaN(schema: z.ZodType): boolean {\n  return schema._zod.traits.has(\"$ZodNaN\");\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":["Strip `z.nan()` branches from unions before conversion.","Normalize NaN to a sentinel (null / specific number / string) at the boundary.","Use `{ unrepresentable: \"any\" }` for schemas that must retain a NaN branch."],"tags":["json-schema","nan","number","unrepresentable"],"analyzedSha":"912f0f51b0ced654d0069741e7160834dca742ee","analyzedAt":"2026-08-03T17:41:55.908Z","schemaVersion":2}