{"record":{"id":"8bb9dce21a42794b","repo":"elastic/elasticsearch","slug":"ordered-are-not-supported","errorCode":null,"errorMessage":"ordered {} are not supported","messagePattern":"ordered (.+?) are not supported","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/ip-location/src/main/java/org/elasticsearch/ingest/geoip/IngestGeoIpMetadata.java","lineNumber":54,"sourceCode":" * Holds the ingest-geoip databases that are available in the cluster state.\n */\npublic final class IngestGeoIpMetadata implements Metadata.ProjectCustom {\n\n    public static final String TYPE = \"ingest_geoip\";\n    private static final ParseField DATABASES_FIELD = new ParseField(\"databases\");\n\n    public static final IngestGeoIpMetadata EMPTY = new IngestGeoIpMetadata(Map.of());\n\n    @SuppressWarnings(\"unchecked\")\n    private static final ConstructingObjectParser<IngestGeoIpMetadata, Void> PARSER = new ConstructingObjectParser<>(\n        TYPE,\n        a -> new IngestGeoIpMetadata(\n            ((List<DatabaseConfigurationMetadata>) a[0]).stream().collect(Collectors.toMap((m) -> m.database().id(), Function.identity()))\n        )\n    );\n    static {\n        PARSER.declareNamedObjects(ConstructingObjectParser.constructorArg(), (p, c, n) -> DatabaseConfigurationMetadata.parse(p, n), v -> {\n            throw new IllegalArgumentException(\"ordered \" + DATABASES_FIELD.getPreferredName() + \" are not supported\");\n        }, DATABASES_FIELD);\n    }\n\n    private final Map<String, DatabaseConfigurationMetadata> databases;\n\n    public IngestGeoIpMetadata(Map<String, DatabaseConfigurationMetadata> databases) {\n        this.databases = Map.copyOf(databases);\n    }\n\n    @Override\n    public String getWriteableName() {\n        return TYPE;\n    }\n\n    @Override\n    public TransportVersion getMinimalSupportedVersion() {\n        return TransportVersion.minimumCompatible();\n    }","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/modules/ip-location/src/main/java/org/elasticsearch/ingest/geoip/IngestGeoIpMetadata.java#L36-L72","documentation":"Thrown by the IngestGeoIpMetadata ConstructingObjectParser when the databases field is provided as an ordered array rather than as named objects. declareNamedObjects installs an order-check callback that rejects array-style input; named objects (a JSON object keyed by database id) are required. IllegalArgumentException surfaces during cluster state / API parsing of the ingest geoip metadata.","triggerScenarios":"Parsing a IngestGeoIpMetadata JSON where DATABASES_FIELD is a JSON array; declareNamedObjects' third lambda fires with the rejection message.","commonSituations":"Hand-crafted API request or external automation sending databases as a list; a serialization library defaulting a Map to an array; version skew where an older client sends array form.","solutions":["Send databases as a JSON object keyed by database id, e.g. {\"databases\": {\"mydb\": {...}}} rather than [{\"name\":\"mydb\",...}].","If integrating via JSON, configure the serializer to emit maps as objects and to skip null keys.","Validate the request body shape against the rest-api-spec before sending."],"exampleFix":"// before\n{\"databases\": [{\"name\":\"city\",\"md5\":\"...\"}]}\n// after\n{\"databases\": {\"city\": {\"name\":\"city\",\"md5\":\"...\"}}}","handlingStrategy":"validation","validationCode":"// before sending, ensure databases is a JSON object, not an array\nObject databases = body.get(\"databases\");\nif (databases instanceof List) {\n    throw new IllegalArgumentException(\"databases must be a JSON object keyed by id, not an array\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always serialize the databases field as a JSON object keyed by database id.","Configure JSON serializers to render Maps as objects, never as arrays.","Validate request bodies against the rest-api-spec before submission.","Add integration tests that send the documented object shape."],"tags":["geoip","parsing","json","api-contract","configuration"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}