{"record":{"id":"26780b0629066acd","repo":"t8y2/dbx","slug":"mongodb-aggregate-option-comment-must-be-a-string","errorCode":null,"errorMessage":"MongoDB aggregate option comment must be a string","messagePattern":"MongoDB aggregate option comment must be a string","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"agents/drivers/mongodb/src/main/java/com/dbx/agent/mongodb/MongoAgent.java","lineNumber":609,"sourceCode":"            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\")) {\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(","sourceCodeStart":591,"sourceCodeEnd":627,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/mongodb/src/main/java/com/dbx/agent/mongodb/MongoAgent.java#L591-L627","documentation":"The 'comment' aggregate option must be a Java String because it is passed to AggregateIterable.comment(String). Any non-string value (number, boolean, Document) fails the instanceof check and IllegalArgumentException is thrown before execution.","triggerScenarios":"Calling aggregate with options like {\"comment\": 12345} or {\"comment\": true} instead of a string such as {\"comment\":\"nightly report run\"}.","commonSituations":"Auto-generated IDs (numbers) used as comments without String.valueOf(); JSON from a loosely-typed producer where the comment field was numeric; copying from code that used the numeric comment variant of the server command.","solutions":["Convert the value to a string before setting it: new Document(\"comment\", String.valueOf(value)).","Use a descriptive string comment suitable for profiling/ops tracing.","Drop the comment option if it is not needed.","Coerce at the config boundary where the options Document is built."],"exampleFix":"// before\nDocument options = new Document(\"comment\", requestId); // requestId is long\n// after\nDocument options = new Document(\"comment\", String.valueOf(requestId));","handlingStrategy":"validation","validationCode":"Object comment = options.get(\"comment\");\nif (comment != null && !(comment instanceof String)) {\n    throw new IllegalArgumentException(\"comment must be a string, got: \" + comment.getClass().getSimpleName());\n}","typeGuard":"static boolean isString(Object v) {\n    return v == null || v instanceof String;\n}","tryCatchPattern":"try {\n    agent.aggregate(db, collection, pipeline, options);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"comment must be a string\")) {\n        options.put(\"comment\", String.valueOf(options.get(\"comment\")));\n        // retry\n    } else throw e;\n}","preventionTips":["Use String.valueOf() on any non-string trace ID before setting comment","Type-check options built from dynamic input","Prefer descriptive string comments for profiling","Schema-validate the options payload at the API edge"],"tags":["mongodb","aggregate","type-validation","comment"],"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"}