{"record":{"id":"22d283ba5206ac36","repo":"elastic/elasticsearch","slug":"required-one-of-fields-but-none-were-specified","errorCode":null,"errorMessage":"Required one of fields {}, but none were specified.","messagePattern":"Required one of fields (.+?), but none were specified\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"libs/x-content/src/main/java/org/elasticsearch/xcontent/ObjectParser.java","lineNumber":342,"sourceCode":"        if (requiredFields != null && requiredFields.isEmpty() == false) {\n            throwMissingRequiredFields(requiredFields);\n        }\n        return value;\n    }\n\n    private void throwExpectedStartObject(XContentParser parser, XContentParser.Token token) {\n        throw new XContentParseException(parser.getTokenLocation(), \"[\" + name + \"] Expected START_OBJECT but was: \" + token);\n    }\n\n    private static void throwMissingRequiredFields(List<String[]> requiredFields) {\n        final StringBuilder message = new StringBuilder();\n        for (int i = 0; i < requiredFields.size(); i++) {\n            if (i > 0) {\n                message.append(\" \");\n            }\n            message.append(\"Required one of fields \").append(Arrays.toString(requiredFields.get(i))).append(\", but none were specified.\");\n        }\n        throw new IllegalArgumentException(message.toString());\n    }\n\n    private static void ensureExclusiveFields(List<List<String>> exclusiveFields) {\n        StringBuilder message = null;\n        for (List<String> fieldset : exclusiveFields) {\n            if (fieldset.size() > 1) {\n                if (message == null) {\n                    message = new StringBuilder();\n                }\n                message.append(\"The following fields are not allowed together: \").append(fieldset).append(\" \");\n            }\n        }\n        if (message != null && message.length() > 0) {\n            throw new IllegalArgumentException(message.toString());\n        }\n    }\n\n    private void maybeMarkExclusiveField(String currentFieldName, List<List<String>> exclusiveFields) {","sourceCodeStart":324,"sourceCodeEnd":360,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/x-content/src/main/java/org/elasticsearch/xcontent/ObjectParser.java#L324-L360","documentation":"Thrown by throwMissingRequiredFields after the ObjectParser finishes consuming all fields and discovers that at least one declared required-field set has zero members present in the input. A required-field set is registered via declareRequiredFieldSet and mandates that at least one field from the set appear in every valid document.","triggerScenarios":"Sending a request body to an endpoint whose ObjectParser declared required field sets (via declareRequiredFieldSet) but omitting every field from at least one of those sets. For example, a settings update that requires at least one of [\"number_of_shards\", \"number_of_replicas\"] but provides neither.","commonSituations":"Omitting a mandatory field group from an index creation or settings update request. Copying a partial template from documentation that does not include the required field. Assuming a field is optional when the parser marks it as required.","solutions":["Read the error message to see which field set is required and add at least one field from that set.","Check the API documentation for required fields on the endpoint you are calling.","Use the endpoint's schema or OpenAPI spec to discover required field groups.","If the field group should not be required, verify the ObjectParser configuration in the server code."],"exampleFix":"// before — missing required field\nPUT /my-index\n{\n  \"mappings\": { \"properties\": { \"name\": { \"type\": \"text\" } } }\n}\n\n// after — required field included (if the parser required it)\nPUT /my-index\n{\n  \"settings\": { \"number_of_shards\": 1 },\n  \"mappings\": { \"properties\": { \"name\": { \"type\": \"text\" } } }\n}","handlingStrategy":"validation","validationCode":"// Before sending, check that at least one field from each required set is present\nList<Set<String>> requiredSets = List.of(Set.of(\"number_of_shards\", \"number_of_replicas\"));\nfor (Set<String> required : requiredSets) {\n    if (required.stream().noneMatch(body::containsKey)) {\n        throw new IllegalArgumentException(\"Missing required field from: \" + required);\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    objectParser.parse(parser, context);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"Required one of fields\")) {\n        return badRequest(e.getMessage());\n    }\n    throw e;\n}","preventionTips":["Review API documentation for required field sets before constructing request bodies.","Build client-side request builders that enforce required fields at compile time.","Write integration tests that verify requests fail with clear messages when required fields are missing."],"tags":["parsing","xcontent","validation","required-field","object-parser"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}