react-jsonschema-form
react-jsonschema-form copied to clipboard
Issue with oneOf Validation in rjsf
Prerequisites
- [X] I have read the documentation
What theme are you using?
validator-ajv8
What is your question?
I'm working with a schema that uses the oneOf keyword to define two options, each with its own set of required fields. However, I'm encountering an issue where, after selecting one option and entering values, the validator incorrectly prompts for required fields from the other option.
Here’s a simplified example of my schema:
{
"oneOf": [
{
"type": "object",
"properties": {
"optionAField1": { "type": "string" },
"optionAField2": { "type": "number" }
},
"required": ["optionAField1"]
},
{
"type": "object",
"properties": {
"optionBField1": { "type": "string" },
"optionBField2": { "type": "number" }
},
"required": ["optionBField1"]
}
]
}
When I select the first option and fill in optionAField1, I receive a validation error indicating that optionBField1 is required, even though it should not be necessary for the chosen option.
Is this a known issue with rjsf, or am I missing something in my schema configuration? How can I resolve this issue?
@dmistry1 can you double-check your schema & reproduction steps? I am trying to use your schema in the Playground here, and I can submit the data without errors
@nickgros Taking the playground that you provided as an example, say a user fills out optionAField2 field which is not required and we call validate. In the screenshot that I have attached, we can see that we get an error must have required property 'optionBField1' even though we selected Option 1.
With your schema, Ajv has no idea whether you picked 'Option 1' or 'Option 2'. That's entirely a UI construct. If you want Ajv to 'know' about the chosen option, you need to encode that choice into the schema. To do that you have a few options.
If/then/else
You could use "if"/"then"/"else" conditions in your schema so only certain subschemas are validated when the choice matches a certain value. See this example. Basically, your optionA subschema is only loaded when the formData option matches the chosen value.
Discriminator
We have some basic support for the OpenAPI discriminator keyword. Unfortunately we don't have many docs that describe how to use this, and actual Ajv support is a bit spotty. @heath-freenome and I had some luck transcribing your schema into the following example, and modifying the Ajv instance to enable discriminator support. We don't have a way to test this in the playground, so if you want to try this you will have to test it on your machine or in something like CodeSandbox.
{
"type": "object",
"definitions": {
"OptionA": {
"type": "object",
"properties": {
"option": {
"type": "string",
"default": "optionA",
"enum": [
"optionA"
]
},
"optionAField1": {
"type": "string"
},
"optionAField2": {
"type": "number"
}
},
"required": [
"optionAField1"
]
},
"OptionB": {
"type": "object",
"properties": {
"option": {
"type": "string",
"default": "optionB",
"enum": [
"optionB"
]
},
"optionBField1": {
"type": "string"
},
"optionBField2": {
"type": "number"
}
},
"required": [
"optionAField1"
]
}
},
"discriminator": {
"propertyName": "option"
},
"oneOf": [
{
"$ref": "#/definitions/OptionA"
},
{
"$ref": "#/definitions/OptionB"
}
],
"required": [
"option"
]
}
@heath-freenome added an option to the playground to test validation with an Ajv instance where the discriminator option is true.
@dmistry1 here's a playground example of the discriminator suggestion. Change the "Validator" option to "AJV 8 (discriminator)"
@nickgros thank you so much for this information.
This issue has been automatically marked as possibly close 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.