{"record":{"id":"f19e111624a81815","repo":"t8y2/dbx","slug":"mongodb-legacy-aggregate-option-hint-must-be-an-ob","errorCode":null,"errorMessage":"MongoDB Legacy aggregate option hint must be an object","messagePattern":"MongoDB Legacy aggregate option hint 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":616,"sourceCode":"        }\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\")) {\n            iterable = iterable.useCursor(aggregateBoolean(options, \"useCursor\"));\n        }\n        return iterable;\n    }\n\n    private static void validateAggregateOptions(Document options) {\n        Set<String> supported = Set.of(\n            \"explain\",\n            \"allowDiskUse\",\n            \"cursor\",\n            \"maxTimeMS\",\n            \"maxAwaitTimeMS\",\n            \"bypassDocumentValidation\",\n            \"collation\",","sourceCodeStart":598,"sourceCodeEnd":634,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/mongodb/src/main/java/com/dbx/agent/mongodb/MongoAgent.java#L598-L634","documentation":"The 'hint' aggregate option must be a Document (an index-key pattern object) because it is cast to Document and passed to AggregateIterable.hint(Document). Any other type (string index name, number) fails the instanceof check and IllegalArgumentException is thrown. The message mentions 'Legacy' because this code path uses the legacy Document-based hint API.","triggerScenarios":"Calling aggregate with options like {\"hint\":\"age_index_1\"} (index name string) or {\"hint\":1} instead of an object such as {\"hint\":{\"age\":1}}.","commonSituations":"Using the shell-style index NAME string, which the legacy hint(Document) overload does not accept; building hint from a flat config string; confusion between hint-by-name and hint-by-key-pattern.","solutions":["Pass the hint as an index key pattern Document: new Document(\"field\", 1) / {\"hint\":{\"field\":1}}.","If you only know the index name, resolve it to its key pattern (or use a driver API accepting an index-name Bson if available in a newer driver).","Parse a JSON key pattern with Document.parse(\"{\\\"age\\\": 1}\").","Omit hint to let the planner choose."],"exampleFix":"// before\nDocument options = new Document(\"hint\", \"age_index_1\");\n// after\nDocument options = new Document(\"hint\", new Document(\"age\", 1));","handlingStrategy":"validation","validationCode":"Object hint = options.get(\"hint\");\nif (hint != null && !(hint instanceof Document)) {\n    throw new IllegalArgumentException(\"hint must be an index key pattern object like {field:1}\");\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(\"hint must be an object\")) {\n        // cannot safely convert an index name to a key pattern — reject or resolve via listIndexes\n        throw new IllegalStateException(\"Resolve index name to its key pattern before hinting\");\n    } else throw e;\n}","preventionTips":["Always hint by key pattern Document, not index-name string","Resolve index names to key patterns via listIndexes if needed","Parse JSON key patterns with Document.parse","Keep index key patterns in config as objects"],"tags":["mongodb","aggregate","type-validation","hint","index"],"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"}