openapi-zod-client icon indicating copy to clipboard operation
openapi-zod-client copied to clipboard

Discriminator unions require enum even if constant

Open cbix opened this issue 9 months ago • 1 comments

Read before opening

  • Did you search the current list of issues ? yes
  • Is your issue related to zod or zodios ? likely not
  • Are you using a Swagger v2 input schema ? no, it's OpenAPI 3
  • Do you really need runtime validation ? no, but the issue doesn't even occur during validation

Describe the bug Our OpenAPI schema contains a value discriminating a union type based on a fixed property type:

"A": {     
  "properties": {
    "type": { 
      "type": "string",
      "const": "a",
      "title": "Type"
    }     
  },    
  "type": "object",
  "required": ["type"],
  "title": "A"
},
"B": {     
  "properties": {
    "type": { 
      "type": "string",
      "const": "b",
      "title": "Type"
    }     
  },    
  "type": "object",
  "required": ["type"],
  "title": "B"
},
"CreateFoo": {
  "properties": {
    "details": {
      "oneOf": [
        { "$ref": "#/components/schemas/A" },
        { "$ref": "#/components/schemas/B" },
      ],
      "title": "Details",
      "discriminator": {
        "propertyName": "type",
        "mapping": {
          "a": "#/components/schemas/A",
          "b": "#/components/schemas/B",
        }
      }
    }
  },
  "type": "object",
  "required": ["details"],
  "title": "CreateFoo"
},

The resulting schema fails with

A discriminator value for key `type` could not be extracted from all schema options

> 340 |     details: z.discriminatedUnion('type', [A, B]),
      |                ^
  341 |   })
  342 |   .passthrough();

  at Object.create (node_modules/zod/lib/types.js:2528:23)
  at Object.discriminatedUnion (src/shared/apiClient.ts:340:16)

Minimal reproduction See excerpt above. I can't share the full original schema but if it helps I'd try to reproduce this with a minimal schema based on that.

Expected behavior Because both A and B have const values, the generated zod schema could probably be a z.literal(..) instead of z.string(), solving this issue.

Additional context I could fix this by changing the schema json like this:

"A": {     
  "properties": {
    "type": { 
      "type": "string",
      "const": "a",
+     "enum": ["a"],
      "title": "Type"
    }     
  },    
  "type": "object",
  "required": ["type"],
  "title": "A"
},

cbix avatar Apr 02 '25 10:04 cbix

same issue here :(

FoHoOV avatar May 11 '25 22:05 FoHoOV