react-jsonschema-form icon indicating copy to clipboard operation
react-jsonschema-form copied to clipboard

Empty enum is blocking dependency after v5.5.1

Open cewald opened this issue 1 year ago • 8 comments
trafficstars

Prerequisites

What theme are you using?

mui

Version

5.5.1

Current Behavior

If I have a first field with an enum and a second dependant field that holds an empty enum at first but should get filled when the first field gets selected, the second dependant field isn't getting filled as long as the enum of the first field is initially empty. If put an initial value in the second dependant fields enum it works fine.

This error came with the version update 5.1.1.

Expected Behavior

Update the dependant field even tough it is an empty enum first.

Steps To Reproduce

You can reproduce it in the playground with the following two schemas.

This is the working one (with an initial string in the dependant enum) (Playground link)

{
  "type": "object",
  "properties": {
    "firstField": {
      "type": "string",
      "title": "First Field",
      "enum": [
        "Value One",
        "Value Two"
      ]
    },
    "dependantField": {
      "title": "Dependant Field",
      "enum": [
        "Select a value in First field"
      ],
      "readOnly": true
    }
  },
  "required": [
    "firstField",
    "dependantField"
  ],
  "dependencies": {
    "firstField": {
      "oneOf": [
        {
          "properties": {
            "firstField": {
              "enum": [
                "Value One"
              ]
            },
            "dependantField": {
              "enum": [
                "More Values",
                "Even More Values",
                "Enough"
              ],
              "readOnly": false
            }
          }
        },
        {
          "properties": {
            "firstField": {
              "enum": [
                "Value Two"
              ]
            },
            "dependantField": {
              "enum": [
                "Other Values",
                "Even More Other Values",
                "Enough now"
              ],
              "readOnly": false
            }
          }
        }
      ]
    }
  }
}

And with this the one its broken since the update (empty initial enum) and wont update the second dependant field: (Playground link)

{
  "type": "object",
  "properties": {
    "firstField": {
      "type": "string",
      "title": "First Field",
      "enum": [
        "Value One",
        "Value Two"
      ]
    },
    "dependantField": {
      "title": "Dependant Field",
      "enum": [],
      "readOnly": true
    }
  },
  "required": [
    "firstField",
    "dependantField"
  ],
  "dependencies": {
    "firstField": {
      "oneOf": [
        {
          "properties": {
            "firstField": {
              "enum": [
                "Value One"
              ]
            },
            "dependantField": {
              "enum": [
                "More Values",
                "Even More Values",
                "Enough"
              ],
              "readOnly": false
            }
          }
        },
        {
          "properties": {
            "firstField": {
              "enum": [
                "Value Two"
              ]
            },
            "dependantField": {
              "enum": [
                "Other Values",
                "Even More Other Values",
                "Enough now"
              ],
              "readOnly": false
            }
          }
        }
      ]
    }
  }
}

Environment

- OS: Debian, Ubuntun, MacOSX
- Node: 20.17.0
- npm: 10.8.2

Anything else?

I guess I'v nailed it down to this two commit: ~~https://github.com/rjsf-team/react-jsonschema-form/commit/f34a7a2997e2f520a3677b67629d8f386463f354~~ https://github.com/rjsf-team/react-jsonschema-form/commit/ff46301dbbeb951758c5ee1b2ec0f95a459b4dfe <- its this one

And this change in the changelog: https://github.com/rjsf-team/react-jsonschema-form/blob/main/CHANGELOG.md#551

In v5.5.0 my example is working in v5.5.1 not.

cewald avatar Oct 30 '24 06:10 cewald

Afaik in the change above const isValid = validator.isValid(conditionSchema, formData, rootSchema); returns now false and the before term validator.validateFormData(formData, conditionSchema) returns true – I try to find why its considered different. FYI I'm using ajv8 as validator.

cewald avatar Oct 30 '24 08:10 cewald

Afaik in the change above const isValid = validator.isValid(conditionSchema, formData, rootSchema); returns now false and the before term validator.validateFormData(formData, conditionSchema) returns true – I try to find why its considered different. FYI I'm using ajv8 as validator.

The change you are pointing out was done to help improve performance since isValid() is simpler and uses caching better than validateFormData(). If you patch it locally back to the old implementation, does it work again? If so, maybe we can write a test to catch that issue in isValid() and fix it?

heath-freenome avatar Nov 01 '24 19:11 heath-freenome

I see – yes, if I patch it back, it is working.

cewald avatar Nov 01 '24 20:11 cewald

Hmmm, @nickgros Any thoughts on whether we roll back this change?

heath-freenome avatar Nov 05 '24 18:11 heath-freenome

Rolling it back seems appropriate with a test to verify that this is fixed. If someone needs the performance optimizations provided by isValid, it would be on them to to ensure this case still works.

nickgros avatar Nov 05 '24 19:11 nickgros

Hey hey, any progress or decision? I would be fine with a rollback ;)

cewald avatar Dec 10 '24 13:12 cewald

@cewald Yes, let's roll it back. Are you willing to push up the PR for that?

heath-freenome avatar Dec 13 '24 20:12 heath-freenome

@heath-freenome alright no problem, i opened one: #4418

cewald avatar Dec 16 '24 08:12 cewald

@cewald So I did some debugging and it turns out that AJV fails to compile the schema before attempting to validate it with the following error:

Error encountered compiling schema: Error: enum must have non-empty array
    at Object.code (chunk-443NBEJN.js?v=228e667f:4390:17)
    at keywordCode (chunk-443NBEJN.js?v=228e667f:2747:13)
    at chunk-443NBEJN.js?v=228e667f:2508:13
    at CodeGen.code (chunk-443NBEJN.js?v=228e667f:771:11)
    at CodeGen.block (chunk-443NBEJN.js?v=228e667f:898:16)
    at iterateKeywords (chunk-443NBEJN.js?v=228e667f:2505:11)
    at groupKeywords (chunk-443NBEJN.js?v=228e667f:2495:11)
    at chunk-443NBEJN.js?v=228e667f:2480:11
    at CodeGen.code (chunk-443NBEJN.js?v=228e667f:771:11)
    at CodeGen.block (chunk-443NBEJN.js?v=228e667f:898:16) Error Component Stack
    at Form (Form.tsx:293:5)
    at withTheme.tsx:19:8
    at div (<anonymous>)
    at Content2 (react-frame-component.js?v=2d009ad7:97:9)
    at iframe (<anonymous>)
    at Frame2 (react-frame-component.js?v=2d009ad7:195:9)
    at DemoFrame (DemoFrame.tsx:49:11)
    at ErrorBoundary (ErrorBoundary.tsx:18:5)
    at div (<anonymous>)
    at Playground (Playground.tsx:22:38)
    at div (<anonymous>)
    at Layout (Layout.tsx:5:26)
    at App (<anonymous>)

There was a bug in the validator where the validation blew up without reporting any errors using the old validateFormData(formData, conditionSchema) mechanism, thus the old code worked where as the new code handles it properly. I've fixed the bug and updated the playground to properly display the error when you click the Raw Validate button. I'm sorry to say, but you will have to go with the first example, even though it may not be optimal for you. The second example is, in fact, an invalid JSON schema in terms of doing validation. So even if I reverted the code, you would never be able to submit it with proper validation since AJV always blows up.

heath-freenome avatar Aug 15 '25 21:08 heath-freenome