{"record":{"id":"c7b7d730ba51a2d3","repo":"colinhacks/zod","slug":"not-is-not-supported-in-zod-except-not-fo","errorCode":null,"errorMessage":"not is not supported in Zod (except { not: {} } for never)","messagePattern":"not is not supported in Zod \\(except (.+?) \\} for never\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/zod/src/v4/classic/from-json-schema.ts","lineNumber":154,"sourceCode":"  if (path[0] === defsKey) {\n    const key = path[1];\n    if (!key || !ctx.defs[key]) {\n      throw new Error(`Reference not found: ${ref}`);\n    }\n    return ctx.defs[key]!;\n  }\n\n  throw new Error(`Reference not found: ${ref}`);\n}\n\nfunction convertBaseSchema(schema: JSONSchema.JSONSchema, ctx: ConversionContext): ZodType {\n  // Handle unsupported features\n  if (schema.not !== undefined) {\n    // Special case: { not: {} } represents never\n    if (typeof schema.not === \"object\" && Object.keys(schema.not).length === 0) {\n      return z.never();\n    }\n    throw new Error(\"not is not supported in Zod (except { not: {} } for never)\");\n  }\n  if (schema.unevaluatedItems !== undefined) {\n    throw new Error(\"unevaluatedItems is not supported\");\n  }\n  if (schema.unevaluatedProperties !== undefined) {\n    throw new Error(\"unevaluatedProperties is not supported\");\n  }\n  if (schema.if !== undefined || schema.then !== undefined || schema.else !== undefined) {\n    throw new Error(\"Conditional schemas (if/then/else) are not supported\");\n  }\n  if (schema.dependentSchemas !== undefined || schema.dependentRequired !== undefined) {\n    throw new Error(\"dependentSchemas and dependentRequired are not supported\");\n  }\n\n  // Handle $ref\n  if (schema.$ref) {\n    const refPath = schema.$ref;\n    if (ctx.refs.has(refPath)) {","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/colinhacks/zod/blob/2d90846af918af9602e088812d63a035d47cdbe4/packages/zod/src/v4/classic/from-json-schema.ts#L136-L172","documentation":"Thrown by convertBaseSchema (packages/zod/src/v4/classic/from-json-schema.ts:154) when the source JSON Schema uses the `not` keyword in any form other than the special `{ not: {} }` (which Zod maps to z.never()). Zod has no general negation combinator, so the converter deliberately rejects non-trivial `not` clauses rather than silently dropping the constraint.","triggerScenarios":"Calling fromJSONSchema on a schema that includes `not` with a non-empty subschema, e.g. `{ not: { type: 'string' } }` or `{ not: { required: ['x'] } }`. Any `not` whose value is an object with at least one keyword triggers the throw.","commonSituations":"Importing schemas authored for stricter JSON Schema validators that use `not` for negative constraints; OpenAPI specs that use `not` to forbid certain shapes; legacy schemas that express 'anything but X' patterns; auto-generated schemas from TypeScript types that include negation.","solutions":["Remove or rewrite the `not` constraint in the source schema before conversion (Zod cannot express it).","If the intent is 'never', use exactly `{ not: {} }` which converts to z.never().","Approximate the negation with a custom .refine() after conversion: `schema.refine((v) => !predicate(v))`.","Use z.union/z.any with explicit allowed shapes instead of a `not` exclusion."],"exampleFix":"// before\nconst schema = { not: { type: 'string' } };\nfromJSONSchema(schema); // throws: not is not supported\n\n// after — approximate with a post-conversion refinement\nconst zodSchema = z.any().refine((v) => typeof v !== 'string');","handlingStrategy":"validation","validationCode":"function assertNoUnsupportedNot(root: unknown) {\n  const visit = (node: unknown): void => {\n    if (Array.isArray(node)) return node.forEach(visit);\n    if (!node || typeof node !== 'object') return;\n    const o = node as Record<string, unknown>;\n    if (o.not !== undefined) {\n      const isEmpty = typeof o.not === 'object' && o.not !== null && Object.keys(o.not).length === 0;\n      if (!isEmpty) throw new Error(`Unsupported non-trivial 'not' found: ${JSON.stringify(o.not)}`);\n    }\n    for (const v of Object.values(o)) visit(v);\n  };\n  visit(root);\n}","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Strip non-trivial `not` keywords before conversion; they have no Zod equivalent.","Use exactly { not: {} } when you mean z.never().","Approximate negation post-conversion with .refine((v) => !predicate(v)).","Maintain a list of unsupported keywords and scan incoming schemas against it."],"tags":["json-schema","from-json-schema","conversion","unsupported","not"],"backgroundTag":null,"analyzedSha":"2d90846af918af9602e088812d63a035d47cdbe4","analyzedAt":"2026-08-11T01:21:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-22T11:17:16.035Z"}