t8y2/dbx · error · IllegalArgumentException
MongoDB aggregate option comment must be a string
Error message
MongoDB aggregate option comment must be a string
What it means
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.
Source
Thrown at agents/drivers/mongodb/src/main/java/com/dbx/agent/mongodb/MongoAgent.java:609
iterable = iterable.maxAwaitTime(
aggregateNonNegativeLong(options, "maxAwaitTimeMS"),
TimeUnit.MILLISECONDS
);
}
if (options.containsKey("bypassDocumentValidation")) {
iterable = iterable.bypassDocumentValidation(aggregateBoolean(options, "bypassDocumentValidation"));
}
if (options.containsKey("collation")) {
Object rawCollation = options.get("collation");
if (!(rawCollation instanceof Document collation)) {
throw new IllegalArgumentException("MongoDB aggregate option collation must be an object");
}
iterable = iterable.collation(collationOrNull(collation));
}
if (options.containsKey("comment")) {
Object comment = options.get("comment");
if (!(comment instanceof String)) {
throw new IllegalArgumentException("MongoDB aggregate option comment must be a string");
}
iterable = iterable.comment((String) comment);
}
if (options.containsKey("hint")) {
Object hint = options.get("hint");
if (!(hint instanceof Document)) {
throw new IllegalArgumentException("MongoDB Legacy aggregate option hint must be an object");
}
iterable = iterable.hint((Document) hint);
}
if (options.containsKey("useCursor")) {
iterable = iterable.useCursor(aggregateBoolean(options, "useCursor"));
}
return iterable;
}
private static void validateAggregateOptions(Document options) {
Set<String> supported = Set.of(View on GitHub (pinned to c0390bff16)
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.
Example fix
// before
Document options = new Document("comment", requestId); // requestId is long
// after
Document options = new Document("comment", String.valueOf(requestId)); Defensive patterns
Strategy: validation
Validate before calling
Object comment = options.get("comment");
if (comment != null && !(comment instanceof String)) {
throw new IllegalArgumentException("comment must be a string, got: " + comment.getClass().getSimpleName());
} Type guard
static boolean isString(Object v) {
return v == null || v instanceof String;
} Try / catch
try {
agent.aggregate(db, collection, pipeline, options);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("comment must be a string")) {
options.put("comment", String.valueOf(options.get("comment")));
// retry
} else throw e;
} Prevention
- 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
When it happens
Trigger: Calling aggregate with options like {"comment": 12345} or {"comment": true} instead of a string such as {"comment":"nightly report run"}.
Common situations: 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.
Related errors
- MongoDB aggregate option explain must be a boolean
- MongoDB aggregate option cursor must be an object
- MongoDB aggregate option collation must be an object
- MongoDB Legacy aggregate option hint must be an object
- Unsupported MongoDB aggregate cursor option: ${key}
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/26780b0629066acd.
Report an issue: GitHub.