rjsf-team / react-jsonschema-form

A React component for building Web forms from JSON Schema.
https://rjsf-team.github.io/react-jsonschema-form/
Apache License 2.0
14.1k stars 2.18k forks source link

Validation stops working after schema changes (if it has the same id for root object) #1563

Closed ghbakhtiari closed 2 years ago

ghbakhtiari commented 4 years ago

Description

Hi So my problem was that when the validation was activated for a given schema, and then the schema provided to the form changed, the validation stoped working (silently).

Here is a minimal working sample that you can recreate the bug with.

I spent many hours trying to figure out what is causing this and tried to put debuggers and console.logs all over the library's code.

Finally I found out that inside validate.js file, it only creates a new instance of ajv if the additionalMetaSchemas or customFormats props have changed.

And so, it's using the same (previous) ajv instance when the schema has changed. So after that, in this line, the ajv instance is throwing an error with this message (which is caught):

Error: schema with key or id "root" already exists
    at checkUnique (ajv.js:472)
    at Ajv._addSchema (ajv.js:301)
    at Ajv.validate (ajv.js:94)
    at validateFormData (validate.js:254)
    at Form.validate (Form.js:295)
    ...

I see that the cause of this error is that both the schema's have the same id for the root object.

BTW, I don't know whether or not it's supposed to work this way (break if the root id of the schema doesn't change when the schema itself has), but even so, I think we should properly get notified about the error - instead of validation stopping silently...

So, as a workaround, we can add a random string to the root object's id every time there's a change inside schema. Or remove the root object's id property altogether. But I think this can actually be fixed with some changes to the validation logics (maybe creating a new ajv instance if the schema has changed).

Steps to Reproduce

  1. Go here
  2. Submit the form while it has error (it only has 2 fields and both are required. So you can just submit the empty form)
  3. The form correctly shows the errors
  4. Click on the reFetch button to get a new schema
  5. Submit the empty form again
  6. There's no validation errors!
  7. You can change the schema back to the first version (the first schema in which you activated the validation) and see that validation still works for that.

Expected behavior

I think the proper behavior is to have a working validation regardless of schema changes.

toshgoodson commented 4 years ago

Thanks for figuring out a workaround. I've been scratching my head trying to figure out why one of my more complicated forms refused to validate sometimes.

epicfaace commented 4 years ago

Thanks for reporting. Would we need to create a new ajv instance each time the schema has changed, or might it be enough only to create a new ajv instance only when the schema has changed and the existing schema already has the id key defined?

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Please leave a comment if this is still an issue for you. Thank you.

tamas-kasa commented 1 year ago

This issue still exists in the latest @rjsf/validator-ajv6. I could easily solve this issue by removing the $id property from my json schema but I think it's something that should be solved somehow because I can imagine teams (including ourselves) who what to use the $id property. In my opinion generating a random $id every time the schema changes is a good idea. Any progress on this?