Skip to content

Misleading validation error for anyOf property when required value is invalid #662

@pshevche

Description

@pshevche

Summary

Hey everyone, we try to upgrade from version 1.0.69 to 1.0.77 and observe that the validation errors for a certain scenario changed starting with 1.0.74. The error is a bit misleading and I'd like to get your thoughts on whether the previous behavior can be restored or if it will stay this way. The detailed test case is attached.

To sum it up, we have an object that can either be null or have a required enum property. If the property supplied is invalid, then:

  • before 1.0.74, we would only get a validation error stating that $.optionalObject.value: does not have a value in the enumeration
  • after 1.0.74, we would also get a message that $.optionalObject: object found, null expected which is not true, since optionalObject can be an object, it just happens that this object is not valid.

I'd expect to only get a message about the value in this case.

Reproducer

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.networknt.schema.JsonSchemaFactory;
import com.networknt.schema.SpecVersion;
import com.networknt.schema.ValidationMessage;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

class ReproducerTest {
    private static final String SCHEMA = """
        {
           "$schema": "http://json-schema.org/draft-07/schema#",
           "properties": {
               "optionalObject": {
                   "anyOf": [
                       {
                           "type": "null"
                       },
                       {
                           "type": "object",
                           "properties": {
                               "value": {
                                   "enum": [
                                       "one",
                                       "two"
                                   ]
                               }
                           },
                           "required": [
                               "value"
                           ]
                       }
                   ]
               }
           }
        }""";

    private static final String INVALID_VALUE = """
        {
            "optionalObject": {
                "value": "invalid"
            }
        }""";

    @Test
    void testCorrectErrorForInvalidValue() throws JsonProcessingException {
        var mapper = new ObjectMapper();
        var schema = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7).getSchema(SCHEMA);

        var errors = schema.validate(mapper.readTree(INVALID_VALUE));
        var errorMessages = errors.stream().map(ValidationMessage::getMessage).toList();

        assertTrue(errorMessages.contains("$.optionalObject.value: does not have a value in the enumeration [one, two]"));
        assertFalse(errorMessages.contains("$.optionalObject: object found, null expected"));
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions