{"record":{"id":"c56745878c257564","repo":"t8y2/dbx","slug":"arrayfilters-must-be-an-array","errorCode":null,"errorMessage":"arrayFilters must be an array","messagePattern":"arrayFilters must be an array","errorType":"validation","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"agents/drivers/mongodb/src/main/java/com/dbx/agent/mongodb/MongoAgent.java","lineNumber":1621,"sourceCode":"    }\n\n    static UpdateOptions updateOptionsForWrite(String optionsJson) {\n        UpdateOptions result = new UpdateOptions();\n        if (optionsJson == null || optionsJson.trim().isEmpty()) {\n            return result;\n        }\n        Document options = Document.parse(optionsJson);\n        for (String key : options.keySet()) {\n            if (!\"arrayFilters\".equals(key)) {\n                throw new IllegalArgumentException(\"Unsupported update option: \" + key);\n            }\n        }\n        Object rawFilters = options.get(\"arrayFilters\");\n        if (rawFilters == null) {\n            return result;\n        }\n        if (!(rawFilters instanceof List<?>)) {\n            throw new IllegalArgumentException(\"arrayFilters must be an array\");\n        }\n        List<Document> filters = new ArrayList<>();\n        for (Object filter : (List<?>) rawFilters) {\n            if (!(filter instanceof Document)) {\n                throw new IllegalArgumentException(\"Each arrayFilters entry must be an object\");\n            }\n            filters.add((Document) filter);\n        }\n        return result.arrayFilters(filters);\n    }\n\n    static Document documentForWrite(String docJson) {\n        Document doc = Document.parse(docJson);\n        convertMongoShellDates(doc);\n        return doc;\n    }\n\n    private static boolean isUpdatePipelineJson(String updateJson) {","sourceCodeStart":1603,"sourceCodeEnd":1639,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/mongodb/src/main/java/com/dbx/agent/mongodb/MongoAgent.java#L1603-L1639","documentation":"MongoAgent's arrayFilters handling validates the `arrayFilters` option passed with array-field updates (updateOne/updateMany/findAndModify). The option must be a JSON array; a non-array value (object, string, number) cannot be converted to the List<Document> the MongoDB Java driver requires, so an IllegalArgumentException is thrown before any DB call.","triggerScenarios":"Calling a MongoAgent update method with params options containing `arrayFilters` set to a non-array value, e.g. `{\"arrayFilters\": {\"elem.age\": {\"$gte\": 21}}}` or a JSON string instead of `[{\"elem.age\": {\"$gte\": 21}}]`.","commonSituations":"Hand-writing agent request JSON and confusing the object-vs-array shape of arrayFilters; porting code from drivers where arrayFilters keys look like an object; templating tools that quote the array so it arrives as a string.","solutions":["Pass arrayFilters as a JSON array of objects: `\"arrayFilters\": [{\"elem.age\": {\"$gte\": 21}}]`.","If the value is a single filter object, wrap it in an array literal.","If the value is a JSON-encoded string, decode/parse it into an actual array before sending.","Remove the arrayFilters option entirely if the update does not use the filtered positional `$[<identifier>]` operator."],"exampleFix":"// before\n{\"updateOne\": {\"filter\": {\"grades\": {\"$elemMatch\": {\"level\": {\"$gte\": 90}}}}, \"update\": {\"$set\": {\"grades.$[g].score\": 100}}, \"arrayFilters\": {\"g.level\": {\"$gte\": 90}}}}\n// after\n{\"updateOne\": {\"filter\": {\"grades\": {\"$elemMatch\": {\"level\": {\"$gte\": 90}}}}, \"update\": {\"$set\": {\"grades.$[g].score\": 100}}, \"arrayFilters\": [{\"g.level\": {\"$gte\": 90}}]}}","handlingStrategy":"validation","validationCode":"// Java: validate before sending\nObject af = options.get(\"arrayFilters\");\nif (af != null && !(af instanceof List)) {\n    throw new IllegalArgumentException(\"arrayFilters must be an array of objects\");\n}","typeGuard":"static boolean isArrayFiltersArray(Object v) { return v instanceof List<?> l && l.stream().allMatch(x -> x instanceof java.util.Map); }","tryCatchPattern":"try { agent.updateOne(filter, update, options); }\ncatch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"arrayFilters must be an array\")) {\n    // normalize: wrap single object in a List and retry\n  } else throw e;\n}","preventionTips":["Always model arrayFilters as List<Document> in client code, never Map","Add a shared request-builder helper that normalizes arrayFilters to a list","Unit-test update payloads that use $[<identifier>] operators"],"tags":["mongodb","validation","argument-type","update"],"backgroundTag":"invalid-argument-type","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}