{"record":{"id":"e843a9f775a6245b","repo":"t8y2/dbx","slug":"mongodb-aggregate-option-key-must-be-a-boolean","errorCode":null,"errorMessage":"MongoDB aggregate option ${key} must be a boolean","messagePattern":"MongoDB aggregate option (.+?) must be a boolean","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"agents/drivers/mongodb/src/main/java/com/dbx/agent/mongodb/MongoAgent.java","lineNumber":657,"sourceCode":"        for (String key : options.keySet()) {\n            if (!supported.contains(key)) {\n                throw new IllegalArgumentException(\"Unsupported MongoDB Legacy aggregate option: \" + key);\n            }\n        }\n    }\n\n    private static int aggregateMaxRows(JsonObject params) {\n        long value = params.has(\"limit\") ? params.get(\"limit\").getAsLong() : 100;\n        if (value < 0 || value > Integer.MAX_VALUE) {\n            throw new IllegalArgumentException(\"MongoDB aggregate limit must be between 0 and \" + Integer.MAX_VALUE);\n        }\n        return (int) value;\n    }\n\n    private static boolean aggregateBoolean(Document options, String key) {\n        Object value = options.get(key);\n        if (!(value instanceof Boolean)) {\n            throw new IllegalArgumentException(\"MongoDB aggregate option \" + key + \" must be a boolean\");\n        }\n        return (Boolean) value;\n    }\n\n    private static int aggregateNonNegativeInt(Document options, String key) {\n        long value = aggregateNonNegativeLong(options, key);\n        if (value > Integer.MAX_VALUE) {\n            throw new IllegalArgumentException(\"MongoDB aggregate option \" + key + \" is too large\");\n        }\n        return (int) value;\n    }\n\n    private static long aggregateNonNegativeLong(Document options, String key) {\n        Object value = options.get(key);\n        if (!(value instanceof Number number) || number.doubleValue() != Math.rint(number.doubleValue())) {\n            throw new IllegalArgumentException(\"MongoDB aggregate option \" + key + \" must be a non-negative integer\");\n        }\n        long result = number.longValue();","sourceCodeStart":639,"sourceCodeEnd":675,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/mongodb/src/main/java/com/dbx/agent/mongodb/MongoAgent.java#L639-L675","documentation":"Thrown while validating MongoDB aggregate options when option 'key' is expected to be a boolean (e.g. allowDiskUse) but the JSON value is a string, number, or object. The aggregate helper type-checks known boolean options and rejects the request before building the AggregateOptions.","triggerScenarios":"Thrown at agents/drivers/mongodb/src/main/java/com/dbx/agent/mongodb/MongoAgent.java:657 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Send the option as a JSON boolean (true/false), not \"true\" or 1","Check the option name spelling so the value lands under the intended key"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"for (String key : List.of(\"allowDiskUse\", \"bypassDocumentValidation\", \"useCursor\")) {\n    Object v = options.get(key);\n    if (v != null && !(v instanceof Boolean)) {\n        throw new IllegalArgumentException(key + \" must be a boolean, got: \" + v.getClass().getSimpleName());\n    }\n}","typeGuard":"static boolean isBoolean(Object v) {\n    return v == null || v instanceof Boolean;\n}","tryCatchPattern":"try {\n    agent.aggregate(db, collection, pipeline, options);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().endsWith(\"must be a boolean\")) {\n        // identify key from message and coerce with Boolean.parseBoolean, then retry\n    } else throw e;\n}","preventionTips":["Use real booleans, not 1/0 or \"true\" strings, in option payloads","Parse string flags once at the config boundary","Keep flags in typed config objects rather than raw maps","Test option payloads built from env vars and query params"],"tags":[],"backgroundTag":null,"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"}