t8y2/dbx · error · IllegalArgumentException

MongoDB aggregate option explain must be a boolean

Error message

MongoDB aggregate option explain must be a boolean

What it means

MongoAgent.validateAggregateOptions/aggregateExplain requires the 'explain' aggregate option to be a JSON boolean (true or false) because it is passed directly to the MongoDB driver's explain flag. Passing any other type (string "true", number, object) makes the command document invalid for the driver, so the library throws IllegalArgumentException before sending anything to the server. This is an eager input-type check to fail fast with a clear message.

Source

Thrown at agents/drivers/mongodb/src/main/java/com/dbx/agent/mongodb/MongoAgent.java:548

                throw new IllegalArgumentException("Each MongoDB aggregate pipeline stage must be an object");
            }
            pipeline.add(Document.parse(stage.toString()));
        }
        return pipeline;
    }

    static Document aggregateOptions(JsonObject params) {
        Document options = documentOrNull(params, "options");
        return options == null ? new Document() : options;
    }

    static boolean aggregateExplain(Document options) {
        Object explain = options.get("explain");
        if (explain == null) {
            return false;
        }
        if (!(explain instanceof Boolean)) {
            throw new IllegalArgumentException("MongoDB aggregate option explain must be a boolean");
        }
        return (Boolean) explain;
    }

    static Document buildAggregateCommand(String collection, List<Document> pipeline, Document options) {
        validateAggregateOptions(options);
        Document command = new Document("aggregate", collection).append("pipeline", pipeline);
        for (Map.Entry<String, Object> entry : options.entrySet()) {
            command.append(entry.getKey(), entry.getValue());
        }
        if (!aggregateExplain(options) && !command.containsKey("cursor")) {
            command.append("cursor", new Document());
        }
        return command;
    }

    private static AggregateIterable<Document> applyAggregateOptions(
        AggregateIterable<Document> iterable,

View on GitHub (pinned to c0390bff16)

Solutions

  1. Change the explain value to a real boolean: true or false (unquoted) in the options document.
  2. If the value comes from config/env, coerce it with Boolean.parseBoolean (or a strict parse) before building the options Document.
  3. Remove the explain option entirely if you did not intend to explain — omitting it defaults to false.
  4. Validate the options payload schema at the client boundary before calling the agent.

Example fix

// before
Document options = new Document("explain", "true");
// after
Document options = new Document("explain", Boolean.parseBoolean(String.valueOf(rawExplain)));
Defensive patterns

Strategy: validation

Validate before calling

Object explain = options.get("explain");
if (explain != null && !(explain instanceof Boolean)) {
    throw new IllegalArgumentException("explain must be a boolean, got: " + explain.getClass().getSimpleName());
}

Type guard

static boolean isBoolean(Object v) {
    return v == null || v instanceof Boolean;
}

Try / catch

try {
    agent.aggregate(db, collection, pipeline, options);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("explain must be a boolean")) {
        options.put("explain", Boolean.parseBoolean(String.valueOf(options.get("explain"))));
        // retry or surface a typed validation error
    } else throw e;
}

Prevention

When it happens

Trigger: Calling the aggregate tool/command with options.explain set to a non-boolean, e.g. {"explain": "true"}, {"explain": 1}, or {"explain": null}? No — null is treated as absent; the throw happens for any non-Boolean, non-null value like a string or number.

Common situations: Config read from JSON/YAML where explain was quoted as a string; env-var-driven config parsed as text; hand-written JSON in an MCP client where 1/0 was used instead of true/false; template interpolation turning a boolean into a string.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/052b9c92705a4cf3. Report an issue: GitHub.