{"record":{"id":"3c8894decaffcfcb","repo":"t8y2/dbx","slug":"mongodb-aggregate-option-key-is-too-large","errorCode":null,"errorMessage":"MongoDB aggregate option ${key} is too large","messagePattern":"MongoDB aggregate option (.+?) is too large","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"agents/drivers/mongodb/src/main/java/com/dbx/agent/mongodb/MongoAgent.java","lineNumber":665,"sourceCode":"        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();\n        if (result < 0) {\n            throw new IllegalArgumentException(\"MongoDB aggregate option \" + key + \" must be a non-negative integer\");\n        }\n        return result;\n    }\n\n    static Document buildFindExplainCommand(JsonObject params) {\n        String collection = params.get(\"collection\").getAsString();","sourceCodeStart":647,"sourceCodeEnd":683,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/mongodb/src/main/java/com/dbx/agent/mongodb/MongoAgent.java#L647-L683","documentation":"aggregateNonNegativeInt converts an aggregate option value (e.g. cursor batchSize) from long to int; if the long exceeds Integer.MAX_VALUE it throws IllegalArgumentException naming the key. Values below zero would already have been rejected by aggregateNonNegativeLong. This guards the narrowing cast.","triggerScenarios":"Calling aggregate with {\"cursor\":{\"batchSize\": 99999999999}} — any batchSize (or other int-typed option) larger than 2147483647.","commonSituations":"Copy-pasted placeholder values like 2^40 as a 'max' batch size; JSON numbers parsed as long; misconfigured tooling that multiplies values (e.g. MB-to-bytes conversion on a batch-size setting).","solutions":["Use a realistic batchSize within int range, e.g. 100–10000 documents.","Clamp client-side: Math.min(value, Integer.MAX_VALUE) before sending.","If a very large batch was intended, page through results in multiple calls instead.","Sanitize numeric config at load time with explicit range checks."],"exampleFix":"// before\nlong batchSize = 1L << 40; // far beyond int range\n// after\nint batchSize = (int) Math.min(rawBatchSize, 10000L);","handlingStrategy":"validation","validationCode":"Object bs = cursorDoc.get(\"batchSize\");\nif (bs instanceof Number n && (n.longValue() < 0 || n.longValue() > Integer.MAX_VALUE)) {\n    throw new IllegalArgumentException(\"batchSize must fit in a non-negative int\");\n}","typeGuard":"static boolean isIntSafe(Object v) {\n    return v instanceof Number n && n.longValue() >= 0 && n.longValue() <= Integer.MAX_VALUE;\n}","tryCatchPattern":"try {\n    agent.aggregate(db, collection, pipeline, options);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().endsWith(\"is too large\")) {\n        String key = e.getMessage().replaceFirst(\".* option \", \"\").replace(\" is too large\", \"\");\n        Document doc = (Document) options.get(\"cursor\");\n        doc.put(key, Math.min(((Number) doc.get(key)).longValue(), 10000L).intValue());\n        // retry with clamped value\n    } else throw e;\n}","preventionTips":["Use realistic batch sizes (100–10000), not placeholder maxima","Clamp numeric config at load time to int-safe ranges","Watch for unit-conversion code (MB→bytes) applied to document-count settings","Validate batchSize bounds in client-side schema checks"],"tags":["mongodb","aggregate","range-validation","batchsize","integer-overflow"],"backgroundTag":"parameter-out-of-range","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"}