{"record":{"id":"5c3e2b4771082eb5","repo":"t8y2/dbx","slug":"mongodb-aggregate-option-collation-must-be-an-obje","errorCode":null,"errorMessage":"MongoDB aggregate option collation must be an object","messagePattern":"MongoDB aggregate option collation must be an object","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"agents/drivers/mongodb/src/main/java/com/dbx/agent/mongodb/MongoAgent.java","lineNumber":602,"sourceCode":"                iterable = iterable.batchSize(aggregateNonNegativeInt(cursor, \"batchSize\"));\n            }\n        }\n        if (options.containsKey(\"maxTimeMS\")) {\n            iterable = iterable.maxTime(aggregateNonNegativeLong(options, \"maxTimeMS\"), TimeUnit.MILLISECONDS);\n        }\n        if (options.containsKey(\"maxAwaitTimeMS\")) {\n            iterable = iterable.maxAwaitTime(\n                aggregateNonNegativeLong(options, \"maxAwaitTimeMS\"),\n                TimeUnit.MILLISECONDS\n            );\n        }\n        if (options.containsKey(\"bypassDocumentValidation\")) {\n            iterable = iterable.bypassDocumentValidation(aggregateBoolean(options, \"bypassDocumentValidation\"));\n        }\n        if (options.containsKey(\"collation\")) {\n            Object rawCollation = options.get(\"collation\");\n            if (!(rawCollation instanceof Document collation)) {\n                throw new IllegalArgumentException(\"MongoDB aggregate option collation must be an object\");\n            }\n            iterable = iterable.collation(collationOrNull(collation));\n        }\n        if (options.containsKey(\"comment\")) {\n            Object comment = options.get(\"comment\");\n            if (!(comment instanceof String)) {\n                throw new IllegalArgumentException(\"MongoDB aggregate option comment must be a string\");\n            }\n            iterable = iterable.comment((String) comment);\n        }\n        if (options.containsKey(\"hint\")) {\n            Object hint = options.get(\"hint\");\n            if (!(hint instanceof Document)) {\n                throw new IllegalArgumentException(\"MongoDB Legacy aggregate option hint must be an object\");\n            }\n            iterable = iterable.hint((Document) hint);\n        }\n        if (options.containsKey(\"useCursor\")) {","sourceCodeStart":584,"sourceCodeEnd":620,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/mongodb/src/main/java/com/dbx/agent/mongodb/MongoAgent.java#L584-L620","documentation":"Shared helper aggregateBoolean(options,key) requires the named aggregate option (allowDiskUse, bypassDocumentValidation, useCursor) to be a Boolean because it is returned directly to driver methods like allowDiskUse(boolean). A non-boolean value fails instanceof Boolean and throws IllegalArgumentException with the offending key in the message.","triggerScenarios":"Calling aggregate with e.g. {\"allowDiskUse\":\"true\"}, {\"bypassDocumentValidation\":1}, or {\"useCursor\":\"yes\"} — any non-Boolean, non-null value under one of these keys (missing keys are skipped by containsKey guards).","commonSituations":"Flags sourced from string env vars or query params without conversion; YAML/JSON config with quoted booleans; template rendering that stringified true/false; producers in JavaScript where 1/0 were used.","solutions":["Set the flag as an actual boolean: true/false unquoted in JSON or Boolean.TRUE in Java.","Coerce strings with Boolean.parseBoolean (or strict \"true\"/\"false\" parsing) before building options.","Remove the option if the default (false) behavior is fine.","Validate option types client-side before invoking the agent."],"exampleFix":"// before\nDocument options = new Document(\"allowDiskUse\", \"true\");\n// after\nDocument options = new Document(\"allowDiskUse\", Boolean.parseBoolean(String.valueOf(rawFlag)));","handlingStrategy":"validation","validationCode":"Object collation = options.get(\"collation\");\nif (collation != null && !(collation instanceof Document)) {\n    throw new IllegalArgumentException(\"collation must be an object with a locale, e.g. {locale:'en_US'}\");\n}","typeGuard":"static boolean isDocument(Object v) {\n    return v == null || v instanceof Document;\n}","tryCatchPattern":"try {\n    agent.aggregate(db, collection, pipeline, options);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"collation must be an object\")) {\n        Object raw = options.get(\"collation\");\n        options.put(\"collation\", new Document(\"locale\", String.valueOf(raw)));\n        // retry\n    } else throw e;\n}","preventionTips":["Wrap locale strings in an object: {\"locale\":\"en_US\"}","Never pass collation as a bare string/number","Parse collation JSON with Document.parse when sourced as text","Keep locale+strength in structured config, not flat strings"],"tags":["mongodb","aggregate","type-validation","boolean"],"backgroundTag":"invalid-option-type","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}