Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DiscriminatorNode access on undefined property #1026

Open
pmarschik opened this issue Nov 21, 2024 · 3 comments
Open

DiscriminatorNode access on undefined property #1026

pmarschik opened this issue Nov 21, 2024 · 3 comments
Labels
bug Something isn't working reviewing 👀 Undergoing manual audit to determine if issue should still be active

Comments

@pmarschik
Copy link

Describe the bug

With version 4.2.0 OAS discriminator was changed and now results in "This page crashed": TypeError: undefined is not an object (evaluating 'subProperties[discriminator.propertyName]') errors.

Rolling back to 4.1.0 fixes the issue but shows "circular(InnerClassTypeA)".

Your Environment

  • Version used: 4.2.0

Context

The relevant part of redacted OAS looks like this:

# ...
components:
  schemas:
    OuterClass:
      type: object
      properties:
        _TYPE:
          type: string
          enum:
            - type1
            - type2
        sharedProperty:
          type: string
     discriminator:
       propertyName: _TYPE
       mapping:
         type1: "#components/schemas/OuterClassType1"
         type2: "#components/schemas/OuterClassType2"
    OuterClassType1:
      allOf:
        - $ref: "#components/schemas/OuterClass"
        - type: object
          properties:
            # property named the same but different concrete schema per discriminated property
            innerClass:
              $ref: "#components/schemas/InnerClassTypeA"
    OuterClassType2:
      allOf:
        - $ref: "#components/schemas/OuterClass"
        - type: object
          properties:
            # property named the same but different concrete schema per discriminated property
            innerClass:
              $ref: "#components/schemas/InnerClassTypeB"
    # never used directly but only "inherited" from with allOf
    InnerClass:
      type: object
      properties:
        _TYPE:
          type: string
          enum:
            - typeA
            - typeB
        sharedProperty:
          type: string
     discriminator:
       propertyName: _TYPE
       mapping:
         type1: "#components/schemas/InnerClassTypeA"
         type2: "#components/schemas/InnerClassTypeB"
    InnerClassTypeA:
      allOf:
        - $ref: "#components/schemas/InnerClass"
        - type: object
          properties:
            specificFieldA:
              type: string
    InnerClassTypeB:
      allOf:
        - $ref: "#components/schemas/InnerClass"
        - type: object
          properties:
            specificFieldB:
              type: string
@pmarschik pmarschik added the bug Something isn't working label Nov 21, 2024
@omonk
Copy link
Contributor

omonk commented Dec 6, 2024

PR this was introduced in #1009

We're seeing the same issue as our schema is missing the properties when there is a discriminator

BaseNested:
  type: object
  discriminator:
    propertyName: type
  # properties: <---- Missing this properties value here
  #   type:
  #     type: string
  oneOf:
    - $ref: "#/components/schemas/NestedTypeA"
    - $ref: "#/components/schemas/NestedTypeB"

Related lines

const discriminatorProperty = schema.properties![discriminator.propertyName];

schema.properties![discriminator.propertyName] = {
...schema.properties![discriminator.propertyName],
...subProperties[discriminator.propertyName],
};


I attempted to make some changes to account for the missing schema.properties value. It's only used to resolve the schema type, which assumed would be possible to grab from the resolved mappings that the Object.values(discriminator.mappings) augments

  const discriminatorProperty = schema.properties
    ? schema.properties[discriminator.propertyName]
    : discriminator.mapping[0].properties[discriminator.propertyName];

  const schemaName = getSchemaName(discriminatorProperty);

I've had to just change the schema with a generic object definition such as

properties
  keyName:
    type: object

@sserrata any chances you could share some knowledge around here?

Come to think of it, surely the schemaName will always be an object if we're using a discriminator?

@sserrata
Copy link
Member

Hi @omonk, thanks for help with debugging. This one was a bit tricky but I settled on a fix that I believe should work. I appreciate if you can help test using the latest canary release. Thanks!

@sserrata sserrata added the reviewing 👀 Undergoing manual audit to determine if issue should still be active label Dec 10, 2024
@pmarschik
Copy link
Author

For my usecase the issue persists with 4.3.0, I've worked around it for now by changing my schema:

# ...
components:
  schemas:
    OuterClass:
      type: object
      properties:
        _TYPE:
          type: string
          enum:
            - type1
            - type2
        sharedProperty:
          type: string
     discriminator:
       propertyName: _TYPE
       mapping:
         type1: "#components/schemas/OuterClassType1"
         type2: "#components/schemas/OuterClassType2"
    OuterClassType1:
      allOf:
        - $ref: "#components/schemas/OuterClass"
        - type: object
          properties:
            # property named the same but different concrete schema per discriminated property
            innerClass:
              $ref: "#components/schemas/InnerClassTypeA"
    OuterClassType2:
      allOf:
        - $ref: "#components/schemas/OuterClass"
        - type: object
          properties:
            # property named the same but different concrete schema per discriminated property
            innerClass:
              $ref: "#components/schemas/InnerClassTypeB"
    InnerClassTypeA:
      type: object
      properties:
        specificFieldA:
          type: string
    InnerClassTypeB:
      type: object
      properties:
         specificFieldB:
           type: string

i.e. I've removed the inheritance on the InnerClassTypeA and InnerClassTypeB.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working reviewing 👀 Undergoing manual audit to determine if issue should still be active
Projects
None yet
Development

No branches or pull requests

3 participants